Skip to main content

systemprompt_loader/
error.rs

1//! Error types raised by the loader infrastructure.
2//!
3//! Three thiserror-derived enums cover the public surface:
4//!
5//! - [`ConfigLoadError`] — services-config reading, YAML parsing, include
6//!   resolution, and validation failures.
7//! - [`ConfigWriteError`] — file creation, agent CRUD, and config-file editing
8//!   failures.
9//! - [`ExtensionLoadError`] — manifest discovery and registry lookups.
10//!
11//! All three implement `std::error::Error` and compose with upstream
12//! errors (`std::io::Error`, `serde_yaml::Error`,
13//! `systemprompt_config::ProfileBootstrapError`,
14//! `systemprompt_models::ServicesValidationError`,
15//! `systemprompt_models::ProfileValidationError`) via `#[from]`.
16
17use std::path::PathBuf;
18use thiserror::Error;
19
20#[derive(Debug, Error)]
21pub enum ConfigLoadError {
22    #[error("profile bootstrap unavailable: {0}")]
23    ProfileBootstrap(#[from] systemprompt_config::ProfileBootstrapError),
24
25    #[error("io error at {path}: {source}")]
26    Io {
27        path: PathBuf,
28        #[source]
29        source: std::io::Error,
30    },
31
32    #[error("yaml parse failure at {path}: {source}")]
33    Yaml {
34        path: PathBuf,
35        #[source]
36        source: serde_yaml::Error,
37    },
38
39    #[error(
40        "include file not found: {include}\nReferenced in: {referrer}\nEither create the file or \
41         remove it from the includes list."
42    )]
43    IncludeNotFound { include: PathBuf, referrer: PathBuf },
44
45    #[error("include cycle detected: {chain}")]
46    IncludeCycle { chain: String },
47
48    #[error("duplicate agent definition: {0}")]
49    DuplicateAgent(String),
50
51    #[error("duplicate MCP server definition: {0}")]
52    DuplicateMcpServer(String),
53
54    #[error("duplicate plugin definition: {0}")]
55    DuplicatePlugin(String),
56
57    #[error("duplicate skill definition: {0}")]
58    DuplicateSkill(String),
59
60    #[error("duplicate content source definition: {0}")]
61    DuplicateContentSource(String),
62
63    #[error("duplicate external agent definition: {0}")]
64    DuplicateExternalAgent(String),
65
66    #[error("services config validation failed: {0}")]
67    Validation(String),
68
69    #[error(
70        "include {path} sets `settings:` — settings are only valid in the root config file. Move \
71         the values to the root or remove them from the include."
72    )]
73    IncludeMustNotSetGlobalSettings { path: PathBuf },
74}
75
76#[derive(Debug, Error)]
77pub enum ConfigWriteError {
78    #[error("io error at {path}: {source}")]
79    Io {
80        path: PathBuf,
81        #[source]
82        source: std::io::Error,
83    },
84
85    #[error("yaml serialisation failed: {0}")]
86    YamlEncode(#[from] serde_yaml::Error),
87
88    #[error("Agent file already exists: {0}. Use 'agents edit' to modify.")]
89    AgentFileExists(PathBuf),
90
91    #[error("Agent '{0}' not found in any configuration file")]
92    AgentNotFound(String),
93}
94
95#[derive(Debug, Error)]
96pub enum ExtensionLoadError {
97    #[error("Binary '{name}' not found at {path}")]
98    BinaryNotFound { name: String, path: PathBuf },
99
100    #[error("No manifest.yaml found for extension '{0}' in extensions/")]
101    ManifestMissing(String),
102}
103
104pub type ConfigLoadResult<T> = Result<T, ConfigLoadError>;
105
106pub type ConfigWriteResult<T> = Result<T, ConfigWriteError>;
107
108pub type ExtensionLoadResult<T> = Result<T, ExtensionLoadError>;
109
110#[derive(Debug, Error)]
111pub enum ProfileLoadError {
112    #[error("io error at {path}: {source}")]
113    Io {
114        path: PathBuf,
115        #[source]
116        source: std::io::Error,
117    },
118
119    #[error(transparent)]
120    Profile(#[from] systemprompt_models::profile::ProfileError),
121}
122
123pub type ProfileLoadResult<T> = Result<T, ProfileLoadError>;