#[non_exhaustive]pub enum SubAgentError {
Show 21 variants
Parse {
path: String,
reason: String,
},
Invalid(String),
NotFound(String),
Spawn(String),
ConcurrencyLimit {
active: usize,
max: usize,
},
Cancelled,
InvalidCommand(String),
Transcript(String),
Integrity(String),
AmbiguousId(String, usize),
StillRunning(String),
Memory {
name: String,
reason: String,
},
Io {
path: String,
reason: String,
},
Llm(String),
Channel(String),
TaskPanic(String),
MaxDepthExceeded {
depth: u32,
max: u32,
},
WorktreeSetup(String),
Durable(String),
DelegationDenied {
mode: DelegationMode,
origin: SpawnOrigin,
def_name: String,
},
SessionSpawnLimit {
spawned: usize,
max: usize,
},
}Expand description
All errors that can arise during sub-agent lifecycle operations.
SubAgentError is the single error type for the entire zeph-subagent crate.
Every fallible public function returns Result<_, SubAgentError>.
§Examples
use zeph_subagent::{SubAgentDef, SubAgentError};
let err = SubAgentDef::parse("missing frontmatter").unwrap_err();
assert!(matches!(err, SubAgentError::Parse { .. }));Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Parse
Frontmatter parsing failed (malformed YAML/TOML or missing delimiters).
Invalid(String)
Definition semantics are invalid (e.g. empty name, conflicting tool policies).
NotFound(String)
No definition or running agent with the requested name or ID was found.
Spawn(String)
The background task could not be spawned (OS or tokio error).
ConcurrencyLimit
The manager’s concurrency limit is exhausted; no new agents can be spawned.
Cancelled
The agent loop was cancelled via its tokio_util::sync::CancellationToken.
InvalidCommand(String)
A slash-command string (/agent, /agents) could not be parsed.
Transcript(String)
An I/O operation on a transcript file failed.
Integrity(String)
A transcript’s hash chain failed to verify (issue #6360): a definite tamper verdict, a
partial strip of chain metadata, an unverifiable/possibly-re-keyed chain, or a chained
file read with no history-integrity key configured. Distinct from SubAgentError::Transcript
(JSON-syntax/I-O errors) because a chain break always escalates to a hard failure — even
in TranscriptReader::load’s otherwise-lenient mode — since it invalidates trust in
everything downstream of the break, unlike a single malformed line.
AmbiguousId(String, usize)
An ID prefix matched more than one transcript; provide a longer prefix.
StillRunning(String)
Resume was requested for an agent that is still running.
Memory
A memory directory could not be created or resolved.
Io
A filesystem I/O error unrelated to transcripts.
Llm(String)
The underlying LLM provider returned an error during the agent loop.
Channel(String)
A channel send (status watch, secret approval) failed.
TaskPanic(String)
The tokio task panicked and the join handle propagated the panic.
MaxDepthExceeded
The recursion depth for nested sub-agent spawning exceeded the configured limit.
WorktreeSetup(String)
Worktree creation or cwd setup failed during agent spawn.
This error is returned when permissions.worktree = true and the worktree
manager fails to create a dedicated worktree or cannot restore the working
directory. The agent loop never starts in this case (INV-4).
Durable(String)
The durable promise layer returned an error during subagent spawn or await.
Wraps a zeph_durable::DurableError string so the crate does not take a hard
compile-time dependency on zeph-durable in code paths where the feature is disabled
at runtime (the durable module is always compiled in but the adapter functions are
only called when durable.enabled && durable.subagent).
DelegationDenied
The spawn attempt was rejected by delegation_mode (spec
042-subagent-delegation-mode-parity, issue #5857): either delegation_mode = "disabled" (all spawns rejected) or delegation_mode = "explicit_request_only" and
origin was SpawnOrigin::Autonomous. Distinct from
SubAgentError::ConcurrencyLimit and SubAgentError::MaxDepthExceeded so the
rejection reason is unambiguous in logs (FR-007).
SessionSpawnLimit
The session-wide cumulative spawn budget has been exhausted (issue #6545).
Distinct from SubAgentError::ConcurrencyLimit (bounds in-flight agents) and
SubAgentError::MaxDepthExceeded (bounds recursion depth): this bounds the total
number of subagents spawned over the session’s lifetime, independent of both, so a
shallow, low-concurrency but high-frequency sequential delegation loop is still caught.
The Display string names the config key directly because the only user-visible
surface for most callers is format!("Failed to spawn sub-agent: {e}").
Trait Implementations§
Source§impl Debug for SubAgentError
impl Debug for SubAgentError
Source§impl Display for SubAgentError
impl Display for SubAgentError
Source§impl Error for SubAgentError
impl Error for SubAgentError
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()
Auto Trait Implementations§
impl Freeze for SubAgentError
impl RefUnwindSafe for SubAgentError
impl Send for SubAgentError
impl Sync for SubAgentError
impl Unpin for SubAgentError
impl UnsafeUnpin for SubAgentError
impl UnwindSafe for SubAgentError
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
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> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request