symfonic.capabilities.extensions.errors¶
errors ¶
The failure taxonomy of extension composition (T4.2.2).
Three shapes of failure, and the split matters because they have different audiences.
- :class:
ExtensionContractError— the extension author got the declaration wrong. It fires when a contribution is declared, before anything runs, so it reaches the person who wrote the plugin. - :class:
UntrustedPayloadError— the payload crossing the boundary is not what it claimed to be. It fires while reading an MCP response or a plugin's return value, and it names the field, because the person reading it is operating a deployment someone else's server just answered badly. - :class:
PrivilegeWideningError— the contribution tried to acquire authority it was never granted (AS-INT-3). It is deliberately a sibling rather than a subclass of the other two: an operator who greps their logs for one string wants this one, and burying it under "contract error" would put a privilege-escalation attempt in the same bucket as a typo.
All three parent on :class:ConfigurationError for the same reason the prompt
compiler's do: composition happens before the first provider call, so an
adopter's existing except ConfigurationError around construction already
catches them and nobody has to learn a new root to stay safe.
ExtensionAdmissionError ¶
Bases: ExtensionError
A set of extensions could not be admitted whole (TA8.21).
The other three name what one contribution got wrong. This one names the admission itself: the composition refused some part of what was offered, so admitting the rest would be an extension that is half present — its tools bound and its guardrail dropped, or its policy kept and its prompt silently missing.
Half-present is the failure mode this migration keeps finding, so the admission is atomic: either every contribution offered composes without a refusal, or none of them is admitted and this is raised instead. The detail carries every refusal, because an adopter who has to fix one of them should not have to re-run to discover the second.
ExtensionContractError ¶
Bases: ExtensionError
A contribution's own declaration is malformed.
Raised at declaration time — when the contribution value is validated — not at use time. A tool with no name is not a tool that fails when called; it is a tool that should never have been admitted to the catalogue.
ExtensionError ¶
Bases: ConfigurationError
Root of the extension-composition taxonomy.
Never raised directly. It exists so a composition root can write one
except ExtensionError around the whole compose step and know it caught
every way an extension can refuse to be composed.
PrivilegeWideningError ¶
Bases: ExtensionError
A contribution asked for authority the contributor does not have.
The three cases the composer knows about, all from AS-INT-3: a prompt fragment declaring an authored trust tier, a plugin returning tools after the catalogue is closed, and a policy claiming it can grant rather than only refuse.
UntrustedPayloadError ¶
Bases: ExtensionError
A payload from an MCP server or a plugin failed boundary validation.
Per AS-INT-2 the rejection is typed and names the offending field, because the recipient of this error cannot fix the server that sent it and needs enough detail to report the problem to whoever can.