Skip to main content

PluginError

Enum PluginError 

Source
pub enum PluginError {
Show 15 variants InvalidManifest(String), NotFound(String), AlreadyInstalled(String), Conflict { kind: &'static str, name: String, plugin_id: String, }, UnsupportedPlatform { plugin_id: String, platform: String, }, NotImplemented(String), Registration(String), ArtifactVerificationFailed(String), BundleVerificationFailed(String), ChecksumRequired(String), UntrustedHost(String), UnsignedOrUntrustedSignature(String), RedirectRefused(String), Io(Error), Json(Error),
}

Variants§

§

InvalidManifest(String)

plugin.json failed structural validation (see crate::manifest::PluginManifest::validate) — includes bad ids, bad semver shape, path-traversal attempts, duplicate ids, etc.

§

NotFound(String)

No installed plugin with this id (uninstall/lookup).

§

AlreadyInstalled(String)

A plugin with this id is already installed and install was called with crate::installer::InstallDisposition::FailIfInstalled (the bamboo plugin install verb). Re-run as an upgrade (bamboo plugin update / crate::installer::InstallDisposition::Upgrade) to replace it in place.

§

Conflict

A capability the plugin declares collides with an existing entry in a shared store that is NOT owned by this plugin (a user’s own entry, or another plugin’s). For MCP servers and workflows the install REFUSES rather than clobbering — an MCP server id / workflow filename is referenced elsewhere, so silently overwriting (and later deleting on uninstall) would destroy the user’s entry. kind is a short label such as "mcp server" or "workflow".

Fields

§kind: &'static str
§name: String
§plugin_id: String
§

UnsupportedPlatform

The manifest’s platforms gate excludes the current OS.

Fields

§plugin_id: String
§platform: String
§

NotImplemented(String)

A step this foundation crate deliberately leaves for a later agent (capability-registration wiring — see PLUGIN_PLAN.md). Returned instead of panicking so a partially-stacked branch fails a request cleanly rather than crashing the process.

§

Registration(String)

A capability failed to register/deregister against AppState for a reason OTHER than an ownership conflict (e.g. config.json couldn’t be persisted, a network fetch during source-staging failed). Kept distinct from Self::Conflict (a deliberate REFUSAL, not a failure) so callers/HTTP status mapping can tell “your plugin collides with something” apart from “something broke while trying to register/fetch it”.

§

ArtifactVerificationFailed(String)

A downloaded artifact’s sha256 did not match the manifest’s declared hash. Checked BEFORE unpacking (supply-chain: a URL-installed plugin ships a binary that will be executed) — never surfaced as a generic Registration/InvalidManifest error so callers can distinguish “the author’s manifest is malformed” from “the bytes served at that URL do not match what the manifest promised”.

§

BundleVerificationFailed(String)

A downloaded URL plugin BUNDLE (the plugin.json or the archive containing it — whatever the app layer’s URL-source fetch downloads) did not hash to the caller-supplied expected sha256. Checked BEFORE any extraction/parsing, so a tampered bundle is never trusted even partially. Distinct from Self::ArtifactVerificationFailed (which is pinned by a hash declared INSIDE the manifest — itself only trustworthy once the bundle carrying it is verified): this is the root-of-trust check that closes the circular-trust hole where the manifest’s own artifact hash could be rewritten by whoever tampered with the bundle.

§

ChecksumRequired(String)

A URL plugin install/update was requested with neither a sha256 to verify the downloaded bundle against, nor an explicit allow_unverified opt-in. This is the secure-by-default refusal: a URL install must be either checksum-pinned or an explicit, deliberate risk acceptance — never a silent “download and trust any tar.gz”. Raised BEFORE the URL is ever fetched (no network access happens for a refused install).

§

UntrustedHost(String)

A URL plugin install/update’s host (and path) is not in the configured plugin_trust.trusted_hosts allowlist, and the request did not set allow_untrusted_host. This is the SOURCE-authorization layer (host allowlist) — distinct from Self::BundleVerificationFailed (integrity) and Self::UnsignedOrUntrustedSignature (publisher authenticity). Raised BEFORE the URL is ever fetched, same posture as Self::ChecksumRequired.

§

UnsignedOrUntrustedSignature(String)

A URL plugin bundle is unsigned, or its .sig sidecar does not verify against any key in plugin_trust.trusted_keys, and the request did not set allow_unsigned. This is the PUBLISHER-authenticity layer — a signature proves who produced the bytes, which a bare sha256 (only proving WHAT the bytes are) cannot. Raised after the bundle is downloaded (the signature is verified over the downloaded bytes) but before anything is extracted/parsed.

§

RedirectRefused(String)

A URL plugin install whose bytes will NOT be cryptographically authenticated (no signature required AND no sha256 — the fully opted-out allow_unsigned && allow_unverified, “host-only trust” case) was served an HTTP redirect instead of the bytes. In that case the host allowlist is the SOLE control over where the bytes come from, and it only vetted the FIRST hop — transparently following the redirect would let the bytes come from an unvetted host and silently defeat the allowlist, so redirects are not followed and a redirect response is refused. A trust/authorization refusal (same 403 family as Self::UntrustedHost / Self::UnsignedOrUntrustedSignature), NOT a server error — it tells the caller how to proceed (install from the canonical/final URL, provide a signature/--sha256, or trust the redirect target). Does not arise once a signature or checksum is in play: those authenticate the bytes regardless of which host served them, so redirects are followed in that case.

§

Io(Error)

§

Json(Error)

Trait Implementations§

Source§

impl Debug for PluginError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for PluginError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for PluginError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for PluginError

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for PluginError

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more