cookie_agent_config/
error.rs1use std::{fmt, io, path::PathBuf};
2
3use cookie_agent_identity::{AgentId, ModelKey, ProviderId};
4use thiserror::Error;
5
6#[derive(Error)]
7pub enum ConfigError {
8 #[error("configuration I/O failed: {0}")]
9 Io(#[source] io::Error),
10 #[error("configuration I/O failed at `{path}`: {source}")]
11 FileIo {
12 path: PathBuf,
13 #[source]
14 source: io::Error,
15 },
16 #[error("configuration path is unsafe")]
17 UnsafePath,
18 #[error("configuration changed on disk: {0}")]
19 ChangedOnDisk(PathBuf),
20 #[error("required file was not found")]
21 NotFound,
22 #[error("{0} exceeds its byte limit")]
23 TooLarge(String),
24 #[error("invalid TOML: {0}")]
25 Toml(String),
26 #[error("TOML resource limit or unsupported datetime exceeded")]
27 TomlLimit,
28 #[error("provider `{provider}` is invalid: {source}")]
29 Provider {
30 provider: ProviderId,
31 #[source]
32 source: cookie_agent_models::authoring::AuthoringError,
33 },
34 #[error("{0}")]
35 HeaderOwnership(#[source] cookie_agent_models::authoring::AuthoringError),
36 #[error("invalid runtime setting: {0}")]
37 InvalidRuntime(&'static str),
38 #[error("MCP server `{server}` is invalid: {reason}")]
39 McpServer { server: String, reason: String },
40 #[error("plugin `{plugin}` is invalid: {reason}")]
41 Plugin { plugin: String, reason: String },
42 #[error("environment interpolation is invalid at `{0}`")]
43 Interpolation(String),
44 #[error("environment variable `{variable}` is missing at `{path}`")]
45 MissingEnvironment { path: String, variable: String },
46 #[error("environment variable `{variable}` is not UTF-8 at `{path}`")]
47 NonUtf8Environment { path: String, variable: String },
48 #[error("invalid agent filename `{0}`")]
49 AgentFilename(String),
50 #[error("duplicate agent `{0}`")]
51 DuplicateAgent(AgentId),
52 #[error(
53 "invalid agent preset name `{name}` at `{path}`; expected ^[a-z0-9]+(-[a-z0-9]+)*$ with at most 64 characters"
54 )]
55 AgentPresetName { path: PathBuf, name: String },
56 #[error("agent ID `{0}` is reserved for a built-in agent")]
57 ReservedAgentId(AgentId),
58 #[error("invalid agent document `{path}`: {message}")]
59 AgentDocument { path: PathBuf, message: String },
60 #[error(
61 "agent document `{path}` line {line} contains the removed `schema` field; remove the schema field"
62 )]
63 AgentSchemaRemoved { path: PathBuf, line: usize },
64 #[error(
65 "configuration file `{path}` line {line} contains the removed `schema_version` field; remove the schema_version field"
66 )]
67 ConfigSchemaRemoved { path: PathBuf, line: usize },
68 #[error(
69 "agent `{0}` uses the removed `tools` field; use `permissions` entries to control tool visibility"
70 )]
71 AgentToolsRemoved(AgentId),
72 #[error("agent `{0}` uses the removed `model_fallback` field; use `models` instead")]
73 AgentModelsRenamed(AgentId),
74 #[error("agent `{0}`: timeout_ms is only supported for internal agents")]
75 AgentTimeoutInternalOnly(AgentId),
76 #[error(
77 "agent `{0}` permission resources support only `${{workspace_dir}}`, and only for read or write"
78 )]
79 AgentPermissionExpression(AgentId),
80 #[error("agent YAML resource limit exceeded")]
81 AgentYamlLimit,
82 #[error("agent `{0}` has an empty system prompt")]
83 EmptyPrompt(AgentId),
84 #[error("agent `{agent}` has invalid `{field}`")]
85 AgentField { agent: AgentId, field: &'static str },
86 #[error("agent `{0}` exceeds a list limit")]
87 AgentLimit(AgentId),
88 #[error("primary agent `{0}` requires a nonempty fallback")]
89 PrimaryFallback(AgentId),
90 #[error("agent `{0}` has invalid delegation")]
91 Delegation(AgentId),
92 #[error("agent `{agent}` delegates to unknown agent `{target}`")]
93 UnknownDelegationTarget { agent: AgentId, target: AgentId },
94 #[error("agent `{agent}` delegates to ineligible agent `{target}`")]
95 IneligibleDelegationTarget { agent: AgentId, target: AgentId },
96 #[error("agent `{agent}` delegation pattern `{pattern}` matches no known eligible subagent")]
97 UnmatchedDelegationPattern { agent: AgentId, pattern: String },
98 #[error("agent `{agent}` repeats fallback model `{model}`")]
99 DuplicateFallbackModel { agent: AgentId, model: ModelKey },
100 #[error(
101 "invalid skill name `{name}` at `{path}`; expected ^[a-z0-9]+(-[a-z0-9]+)*$ with at most 64 characters"
102 )]
103 SkillName { path: PathBuf, name: String },
104 #[error(
105 "skill name mismatch at `{path}`: directory `{directory}`, frontmatter `{frontmatter}`"
106 )]
107 SkillNameMismatch {
108 path: PathBuf,
109 directory: String,
110 frontmatter: String,
111 },
112 #[error("invalid skill document `{path}`: {message}")]
113 SkillDocument { path: PathBuf, message: String },
114 #[error("available skill listing cannot fit within one percent of the model context")]
115 SkillListingBudget,
116}
117
118impl fmt::Debug for ConfigError {
119 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
120 formatter
121 .debug_tuple("ConfigError")
122 .field(&self.to_string())
123 .finish()
124 }
125}