Skip to content

symfonic.services.switching.errors

errors

The switching error taxonomy (ERR-1..4).

Every class here answers a different operational question, which is why they are separate types rather than one error with a kind string: "was I not allowed?", "did I lose a race?", "is the vector illegal?", "is the control plane down?", "am I frozen out?" and "is this artifact too old to place?" each lead to a different response, and a caller that has to parse a message to tell them apart will eventually parse it wrong.

BindingUnavailableError

Bases: SwitchingError

CUT-BR-4/CUT-BR-5 — no admissible binding. Never a default fallback.

ConstraintViolationError

Bases: ConfigurationError

CUT-RB-4/CUT-RB-5 — the proposed vector is not a legal combination.

A ConfigurationError on purpose: an illegal vector is a configuration fault whether it arrives from a control-plane proposal or a local override, and library-mode construction must reject it with the taxonomy adopters already catch.

EnvelopeVerificationError

Bases: SwitchingError

ENV-2/ENV-5 — the envelope's signature did not verify.

EnvelopeVersionError

Bases: SwitchingError

ENV-3 — a known-good envelope names a layout or schema we cannot read.

FreezeViolationError

Bases: SwitchingError

SCP-FRZ-1/CUT-RB-7 — a retirement freeze bars this generation.

KeysetUnavailableError

Bases: SwitchingError

KEY-5 — no active key to mint with, or no keyset to verify against.

Availability, never authorization (EMAP-6). A verifier with no keyset must deny, but the holder's token is provably still redeemable — reporting the outage as 401 tells them to stop retrying something that will work again in a minute.

LegacyPinRetiredError

Bases: ConfigurationError

LIB-OV-5 — this release removed the pinned legacy generation.

PinlessArtifactError

Bases: SwitchingError

CUT-PIN-1 — an un-pinned artifact with no configured policy to place it.

StoreUnavailableError

Bases: SwitchingError

The switch-state store could not be reached (control-plane dependency).

SwitchAuthorizationError

Bases: SwitchingError

SCP-AUTH — the actor may not perform this mutation, or authz is down.

SwitchConflictError

Bases: SwitchingError

CUT-SS-2 — a compare-and-swap lost its race. Never a silent overwrite.

SwitchingError

Bases: SymfonicError

Root of the cutover taxonomy. Never raised directly.

Every refusal carries a transport-neutral code (ERR-5). Nothing here knows about HTTP; the code exists so a caller — including one across a package boundary, such as the pause-token reader that only sees an opaque signer port — can tell "you may not" from "I cannot right now" without matching on the exception's type or its message text.