pub enum AgentError {
Show 13 variants
ProcessFailed {
exit_code: i32,
stderr: String,
},
SchemaValidation {
expected: String,
got: String,
debug_messages: Vec<DebugMessage>,
partial_usage: Box<PartialUsage>,
raw_response: Option<String>,
},
BudgetExceeded {
spent_usd: f64,
limit_usd: f64,
debug_messages: Vec<DebugMessage>,
partial_usage: Box<PartialUsage>,
},
Api {
status: Option<u16>,
code: Option<String>,
message: String,
},
PromptTooLarge {
chars: usize,
estimated_tokens: usize,
model_limit: usize,
},
Timeout {
limit: Duration,
},
RateLimited {
provider: String,
retry_after_secs: Option<u64>,
},
HttpProvider {
provider: String,
status_code: u16,
message: String,
},
UnknownToolProfile {
profile: String,
available: Vec<String>,
},
ToolProfileUnsupported {
provider: String,
profile: String,
},
NoCapacity {
kind: String,
next_reset: Option<DateTime<Utc>>,
},
CapacityWait {
kind: String,
wake_at: DateTime<Utc>,
},
AccountNotFound {
name: String,
},
}Expand description
Error specific to agent (AI provider) invocations.
Returned by AgentProvider::invoke and
automatically wrapped into OperationError::Agent when propagated with ?.
Variants§
ProcessFailed
The agent process exited with a non-zero status code.
SchemaValidation
The agent output did not match the expected schema.
Fields
debug_messages: Vec<DebugMessage>Verbose conversation trace captured before the validation failure.
Populated when the agent ran in verbose (stream-json) mode so that callers can persist the debug trail even on error paths.
partial_usage: Box<PartialUsage>Partial usage data from the CLI response, available even though
structured output extraction failed. Boxed to keep AgentError
small on the stack.
BudgetExceeded
The agent stopped because it exhausted its configured USD budget.
Distinct from SchemaValidation: retrying
costs money and cannot succeed, since the budget is already spent. Treated
as non-retryable by is_retryable at the
operation level and by the engine at the run level.
Fields
debug_messages: Vec<DebugMessage>Verbose conversation trace captured before the budget ran out.
partial_usage: Box<PartialUsage>Usage data reported alongside the budget error. Boxed to keep
AgentError small on the stack.
Api
The model API refused the request the Claude CLI sent.
Built from a CLI result with is_error: true: the CLI reached the API,
got an error back and wrote it in place of an answer. Structured output
is never validated against it. is_retryable
retries it only when status is absent, 429 or 5xx (529 overloaded
included): a 4xx such as claude_code_version_too_old or an unknown
model fails the same way on every attempt.
§Examples
use ironflow_core::error::AgentError;
let err = AgentError::Api {
status: Some(400),
code: Some("claude_code_version_too_old".to_string()),
message: "API Error: 400 Claude Code 2.1.274 does not support this model".to_string(),
};
assert!(err.to_string().contains("claude_code_version_too_old"));Fields
status: Option<u16>HTTP status the API answered with (api_error_status), absent when
the CLI did not report one.
PromptTooLarge
The prompt exceeds the model’s context window.
Returned before spawning the process when the estimated token count exceeds the model’s known limit.
chars- number of characters in the combined prompt (system + user).estimated_tokens- approximate token count (chars / 4).model_limit- the model’s context window in tokens.
Fields
Timeout
The agent did not complete within the configured timeout.
RateLimited
The provider returned HTTP 429 Too Many Requests.
Fields
HttpProvider
The provider returned an unexpected HTTP error or a transport-level failure.
When status_code is 0, no HTTP response was received (connection failure,
DNS resolution error, TLS handshake failure, or response body read error).
Fields
UnknownToolProfile
The step asked for a tool profile the provider does not have.
Never falls back to other tools: a typo must not widen what the model can do. Deterministic, so never retried.
Fields
ToolProfileUnsupported
The step asked for a tool profile, but the provider cannot apply one.
Claude CLI providers pick their tools with allowed_tools and MCP
configuration; they refuse a profile rather than ignore it.
Fields
NoCapacity
No provider account can run the step, and the run will not wait for one.
Returned when every targeted account (or the worker’s own token) is
rate limited and the next reset is unknown or further away than the
step’s max_capacity_wait, or when that wait is Duration::ZERO
(fast fail). Never retried: replaying it at once hits the same limits.
§Examples
use ironflow_core::error::AgentError;
let err = AgentError::NoCapacity {
kind: "claude".to_string(),
next_reset: None,
};
assert!(err.to_string().contains("no capacity for claude"));Fields
CapacityWait
Not a failure: asks the engine to suspend the run until wake_at.
Returned by the account-aware provider when every targeted account is
rate limited but capacity comes back within the step’s
max_capacity_wait. The engine puts the run to sleep and re-executes
the step from zero when it wakes, or earlier when an account of kind
is added, re-enabled or gets a new token. Never retried.
§Examples
use chrono::Utc;
use ironflow_core::error::AgentError;
let err = AgentError::CapacityWait {
kind: "claude".to_string(),
wake_at: Utc::now(),
};
assert!(err.to_string().contains("waiting for claude capacity"));Fields
AccountNotFound
The step asked for a provider account by name and none matches.
Never falls back to another account or to the worker’s own token: a step pinned to an account must not silently spend another one.
§Examples
use ironflow_core::error::AgentError;
let err = AgentError::AccountNotFound {
name: "team-a".to_string(),
};
assert_eq!(err.to_string(), "provider account 'team-a' not found");Trait Implementations§
Source§impl Debug for AgentError
impl Debug for AgentError
Source§impl Display for AgentError
impl Display for AgentError
Source§impl Error for AgentError
impl Error for AgentError
1.30.0 · 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()