Skip to main content

cookie_agent_config/
error.rs

1use 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}