Skip to main content

zeph_plugins/
error.rs

1// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Error types for plugin operations.
5
6use std::path::PathBuf;
7
8/// Errors that can occur during plugin install, remove, or list operations.
9#[derive(Debug, thiserror::Error)]
10pub enum PluginError {
11    /// The plugin manifest (`plugin.toml`) is missing or cannot be parsed.
12    #[error("invalid plugin manifest: {0}")]
13    InvalidManifest(String),
14
15    /// The plugin name is invalid (empty, contains path separators, or reserved).
16    #[error("invalid plugin name {name:?}: {reason}")]
17    InvalidName { name: String, reason: String },
18
19    /// A plugin MCP entry declares a command not in `mcp.allowed_commands`.
20    #[error(
21        "plugin MCP server {id:?} spawns command {command:?}, which is not in mcp.allowed_commands"
22    )]
23    DisallowedMcpCommand { id: String, command: String },
24
25    /// A plugin skill name conflicts with an existing managed (user) skill.
26    #[error("plugin skill {name:?} conflicts with an existing managed skill")]
27    SkillNameConflictWithManaged { name: String },
28
29    /// A plugin skill name conflicts with a compile-time bundled skill.
30    #[error("plugin skill {name:?} conflicts with a bundled skill")]
31    SkillNameConflictWithBundled { name: String },
32
33    /// A plugin skill name conflicts with a skill from another installed plugin.
34    #[error("plugin skill {name:?} conflicts with skill from plugin {plugin:?}")]
35    SkillNameConflictWithPlugin { name: String, plugin: String },
36
37    /// A plugin's `[config]` section contains a key not in the tighten-only safelist.
38    #[error(
39        "plugin config overlay key {key:?} is not allowed; only tools.blocked_commands, tools.allowed_commands, and skills.disambiguation_threshold may be overridden"
40    )]
41    UnsafeOverlay { key: String },
42
43    /// A `[[skills]] path` entry does not contain a valid `SKILL.md` file.
44    #[error("plugin skill entry at {path:?} does not contain a SKILL.md file")]
45    SkillEntryMissing { path: PathBuf },
46
47    /// The plugin directory does not exist or cannot be read.
48    #[error("plugin not found: {name}")]
49    NotFound { name: String },
50
51    /// The plugin source path or URL is invalid.
52    #[error("invalid plugin source {path:?}: {reason}")]
53    InvalidSource { path: String, reason: String },
54
55    /// A filesystem operation failed.
56    #[error("filesystem error at {path}: {source}")]
57    Io {
58        path: PathBuf,
59        #[source]
60        source: std::io::Error,
61    },
62
63    /// TOML serialization/deserialization error.
64    #[error("TOML error: {0}")]
65    Toml(#[from] toml::de::Error),
66
67    /// TOML serialization error.
68    #[error("TOML serialization error: {0}")]
69    TomlSer(#[from] toml::ser::Error),
70}