pub enum InferenceError {
Show 20 variants
ModelNotFound(String),
NoEligibleModel {
excluded_models: String,
},
DownloadFailed(String),
InferenceFailed(String),
CatalogPreconditionMismatch {
detail: String,
},
ControlledTermination,
ModelManagement(ModelManagementError),
LocalResourceBlocked {
preflight: LocalLoadPreflight,
recovery: String,
},
Transient {
status: Option<u16>,
message: String,
},
DeadlineExceeded {
applied_ms: u64,
elapsed_ms: u64,
last_error: String,
},
UnsupportedMode {
mode: &'static str,
backend: &'static str,
reason: &'static str,
},
ProviderAccount {
provider: String,
status: u16,
message: String,
},
ProviderKeyMissing {
provider: String,
model: String,
env_vars: Vec<String>,
message: String,
},
CredentialUnavailable {
provider: String,
model: String,
reason: CredentialFailure,
detail: String,
},
WorkspaceRequired {
provider: String,
detail: String,
},
ContentRefused {
provider: String,
kind: Option<String>,
code: Option<String>,
message: String,
},
GatewayUnconfigured {
provider: String,
namespace: String,
status: u16,
message: String,
},
TokenizationError(String),
DeviceError(String),
Io(Error),
}Variants§
ModelNotFound(String)
NoEligibleModel
Adaptive routing could not honor a caller-required model separation boundary. Raised before dispatch, so no excluded backend serves even a failed attempt.
DownloadFailed(String)
InferenceFailed(String)
CatalogPreconditionMismatch
The caller bound inference to a catalog row/revision that no longer matches the daemon’s request snapshot. This is an optimistic concurrency rejection, not a provider failure; it must fail before any dispatch and retain a typed wire mapping at the daemon boundary.
ControlledTermination
Exact isolated-worker kill + wait confirmed termination for this request. The server-owned registry decides whether the outward terminal is cancel or deadline; the inference engine uses this sentinel only to stop retries/fallbacks without penalizing model health.
ModelManagement(ModelManagementError)
LocalResourceBlocked
A CAR-managed local model could not be admitted without violating the user’s saved allocation or the machine’s live emergency reserve.
Transient
A remote call that failed on a retryable class — 5xx / 429 / 529 /
timeout / connection reset — after the bounded retry budget was
exhausted. Distinct from InferenceError::InferenceFailed so a
caller can tell “infra blip, safe to re-run” from “the request itself
is wrong” (4xx / auth / validation). status carries the final HTTP
status when the failure was an HTTP response; None for a transport
or timeout error. Used by car run-task to classify a run as
infra_inference (re-run) vs a non-retryable failure (alert).
DeadlineExceeded
The CALLER’S armed deadline (infer.deadline) elapsed while the remote
request was still in flight or before a retry could fit inside what
remained. Distinct from InferenceError::Transient — this is not an
infra blip and re-running with the same deadline hits the same wall;
the caller asked for exactly this bound and the error names it so the
termination is attributable to the deadline that was applied (car-eyj:
the old shape reported -32603 transient at a ceiling no config exposed).
UnsupportedMode
A request mode is accepted on the public surface but the
selected backend hasn’t wired it yet. Distinct from
InferenceFailed so callers can distinguish “backend can’t”
from “backend tried and something went wrong”.
ProviderAccount
The provider account rejected the call — key absent or rejected (401/403), or out of credits/quota (402).
Account-wide, so it says nothing about the model that happened to be
selected. Booking it as a model failure benches healthy models over a
billing problem, and — because the health EMA is a 30-day window and the
circuit breaker has its own cooldown — the penalty outlives the fix: the
user tops up their credits and the router still avoids the models
(Parslee-ai/car#650). Distinct from InferenceFailed so the dispatch
loop can resolve it as an unattributed receipt instead.
provider is the schema’s provider label, so the dispatch loop can drop
every remaining candidate from the same account rather than replaying
the identical rejection down the fallback chain.
ProviderKeyMissing
A remote provider key could not be resolved before dispatch.
Typed separately so outcome tracking can keep a missing key out of model
health and the per-model circuit breaker. Its Display deliberately
remains byte-identical to the former InferenceError::InferenceFailed
rendering: string consumers include the native coder’s Parslee-only
wait-for-sign-in gate, and classifying an OpenRouter or generic provider
key as Parslee auth would wait on the wrong remedy (Parslee-ai/car#1544).
Fields
No usable credential for a provider — and why, as data rather than prose.
The message text already distinguished the cases (#803), but only in the
text: a consumer wanting to branch on “token aged out mid-run” versus
“never signed in” had to substring-match English that could be reworded
at any time. #797 asked for the distinction to be matchable
programmatically, which is what CredentialFailure is for.
The Display output opens with the historical prefix verbatim —
no credential for proprietary provider '<provider>'. That is load
bearing, not cosmetic: native_loop::is_auth_failure (which drives the
wait-for-sign-in path) and the coder-ab harness’s INFRA_MARKERS (which
keeps auth casualties out of a benchmark denominator) both classify on
it as a substring. Rewording the opening would silently reclassify auth
failures as ordinary errors in both.
WorkspaceRequired
The credential works, but the account behind it has no workspace, so there is nothing to bill inference to and no org id to address it at.
A configuration failure, deliberately not an auth one. The person is
signed in; telling them to sign in again is wrong advice, and the
coder’s sign-in wait (native_loop::is_auth_failure, which classifies on
[AUTH_FAILURE_MESSAGE_MARKERS]) would park an unattended build on a
remedy that cannot resolve it. The Display text is therefore required
to match no auth marker — workspace_required_reads_as_configuration_ not_sign_in pins that. Rewording it needs that test re-run, not
overridden.
Typed rather than left as InferenceFailed prose (its shape until
2026-09-16) so the out-of-the-box agent can end a turn with the
no_workspace reason and a host can offer “finish setting up at
parslee.ai” instead of a sign-in button that leads back here.
Fields
ContentRefused
The request was refused on content grounds by something in front of the model — a gateway safety filter, not the model’s own judgement.
Distinct from InferenceFailed because the three things a caller wants
to do about it are all different from what they would do about a crash,
and all three were impossible while it looked like one
(Parslee-ai/car#796):
- a benchmark can score it as a policy refusal instead of counting a crash, or silently inflating a pass rate by dropping it;
- a retry loop can stop, rather than burning its budget re-sending a decision that will never change;
- an operator can tell a content ruling from a misconfiguration.
This says nothing about whether the refusal was correct. CAR is reporting that something upstream declined the content, not endorsing the call — an adversarial-safety suite is supposed to send input like this, and a gateway that drops a variable fraction of it cannot be a substrate for that measurement. Making the refusal legible is the part CAR owns.
Fields
GatewayUnconfigured
A managed gateway has no upstream configured for an entire namespace of models it otherwise advertises.
Environment-scoped, one level up from Self::ProviderAccount: the
account is fine and the credential is fine — the deployment was never
given an upstream to proxy to. Every model in the namespace fails it
identically, so none of them deserves the health penalty, and retrying
the next one down the fallback chain replays the same rejection.
Kept distinct from ProviderAccount because the remedy is different and
belongs to a different person: an account rejection is the user’s to fix
(top up credits, re-add a key), while this one is an operator
provisioning gap the user cannot act on at all. Collapsing them would
tell users to check a credential that is working.
namespace is the model-id prefix the condition covers, so the dispatch
loop can drop every remaining candidate under it (Parslee-ai/car#786).
TokenizationError(String)
DeviceError(String)
Io(Error)
Trait Implementations§
Source§impl Debug for InferenceError
impl Debug for InferenceError
Source§impl Display for InferenceError
impl Display for InferenceError
Source§impl Error for InferenceError
impl Error for InferenceError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl From<Error> for InferenceError
impl From<Error> for InferenceError
Source§impl From<LocalAdmissionError> for InferenceError
impl From<LocalAdmissionError> for InferenceError
Source§fn from(error: LocalAdmissionError) -> Self
fn from(error: LocalAdmissionError) -> Self
Source§impl From<ModelManagementError> for InferenceError
impl From<ModelManagementError> for InferenceError
Source§fn from(source: ModelManagementError) -> Self
fn from(source: ModelManagementError) -> Self
Source§impl From<RunnerError> for InferenceError
impl From<RunnerError> for InferenceError
Source§fn from(value: RunnerError) -> Self
fn from(value: RunnerError) -> Self
Auto Trait Implementations§
impl !RefUnwindSafe for InferenceError
impl !UnwindSafe for InferenceError
impl Freeze for InferenceError
impl Send for InferenceError
impl Sync for InferenceError
impl Unpin for InferenceError
impl UnsafeUnpin for InferenceError
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> ToCompactString for Twhere
T: Display,
impl<T> ToCompactString for Twhere
T: Display,
Source§fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
ToCompactString::to_compact_string() Read moreSource§fn to_compact_string(&self) -> CompactString
fn to_compact_string(&self) -> CompactString
CompactString. Read more