zeph_orchestration/error.rs
1// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use zeph_subagent::SubAgentError;
5
6/// All error variants produced by the orchestration subsystem.
7///
8/// Variants are exhaustive — callers that match on this type should use a
9/// `_ => …` arm to stay robust against future additions.
10///
11/// # Fail-open policy
12///
13/// LLM-backed steps (verification, replan) are always fail-open: on failure
14/// they log a warning and continue rather than returning an error. Only
15/// structural invariant violations and hard configuration errors propagate as
16/// `Err`.
17///
18/// # Examples
19///
20/// ```rust
21/// use zeph_orchestration::OrchestrationError;
22///
23/// fn describe(err: &OrchestrationError) -> &'static str {
24/// match err {
25/// OrchestrationError::CycleDetected => "graph has a cycle",
26/// OrchestrationError::Disabled => "orchestration is off",
27/// _ => "other orchestration error",
28/// }
29/// }
30///
31/// let err = OrchestrationError::CycleDetected;
32/// assert_eq!(describe(&err), "graph has a cycle");
33/// ```
34#[derive(Debug, thiserror::Error)]
35pub enum OrchestrationError {
36 /// Orchestration is disabled in configuration.
37 #[error("orchestration is disabled")]
38 Disabled,
39
40 /// The LLM planner failed to produce a valid task graph.
41 #[error("planning failed: {0}")]
42 PlanningFailed(String),
43
44 /// The task graph structure is invalid (e.g. wrong task-id invariant, bad reference).
45 #[error("invalid graph: {0}")]
46 InvalidGraph(String),
47
48 /// A cycle was detected during topological sort of the task graph.
49 #[error("cycle detected in task graph")]
50 CycleDetected,
51
52 /// A `TaskId` or task title lookup yielded no result.
53 #[error("task not found: {0}")]
54 TaskNotFound(String),
55
56 /// No agent in the available pool can be routed to a task.
57 #[error("no agent available for task: {0}")]
58 NoAgentAvailable(String),
59
60 /// A `GraphId` could not be found in persistence.
61 #[error("graph not found: {0}")]
62 GraphNotFound(String),
63
64 /// An internal scheduler invariant was violated.
65 #[error("scheduler error: {0}")]
66 Scheduler(String),
67
68 /// Result aggregation failed and the fallback path also failed.
69 #[error("aggregation failed: {0}")]
70 AggregationFailed(String),
71
72 /// A database read/write or serialization error in graph persistence.
73 #[error("persistence error: {0}")]
74 Persistence(String),
75
76 /// A task exceeded its per-task wall-clock timeout.
77 #[error("task timed out: {0}")]
78 TaskTimeout(String),
79
80 /// The scheduler or a task was canceled by the caller.
81 #[error("canceled")]
82 Canceled,
83
84 /// A `/plan` CLI command could not be parsed.
85 #[error("invalid command: {0}")]
86 InvalidCommand(String),
87
88 /// Hard invariant violation during verification (e.g. cycle detected after `inject_tasks`).
89 ///
90 /// Never used for LLM call failures — those are fail-open and only log a warning.
91 #[error("verification failed: {0}")]
92 VerificationFailed(String),
93
94 /// A required configuration value is missing or out of range.
95 #[error("invalid configuration: {0}")]
96 InvalidConfig(String),
97
98 /// Propagated error from a sub-agent execution.
99 #[error(transparent)]
100 SubAgent(#[from] SubAgentError),
101}