Skip to main content

RuntimeError

Enum RuntimeError 

Source
#[non_exhaustive]
pub enum RuntimeError {
Show 30 variants PolicyDenied(PolicyError), Delegation(DelegationError), TaskClaim(ClaimError), ProposalWithheld { task: String, reason: Withheld, }, TaskChanged { task: String, }, PlanContract(String), UnknownTenant(String), ReservedEventKind { kind: String, }, PolicyBundleChanged { recorded: Option<Digest>, configured: Option<Digest>, }, DeclarationChanged { agent: String, recorded: Digest, configured: Digest, }, DeclarationPinMismatch { agent: String, expected: Digest, found: Option<Digest>, }, SubjectUnbound { binding: String, reason: String, }, CanonicalizationChanged { recorded: u16, implemented: u16, }, PayloadsErased { run: String, }, PayloadsSealed { run: String, }, NoCaseStore { run: String, case: String, }, NoProvider { target: String, available: Vec<String>, }, QuotaExceeded(QuotaError), Draining, QuotaSettlementPending { run: String, epoch: u64, detail: String, }, ChainBroken { seq: Seq, detail: String, }, Fenced { run: String, held: u64, current: u64, }, LeaseHeld { run: String, owner: String, remaining_secs: u64, }, NotQuarantined { run: String, status: String, }, NotUndecided { run: String, effect: String, }, CannotUnwind { run: String, }, AlreadyConcluded { run: String, outcome: String, }, ControlStands { run: String, detail: String, }, Store(StoreError), Encoding(Error),
}
Expand description

Failures reaching the operator.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

PolicyDenied(PolicyError)

§

Delegation(DelegationError)

The delegation chain presented for this run cannot act here, now.

Its own variant rather than a PolicyDenied: no rule fired, and the two call for different responses — a denial is an answer to retry nowhere, an expired chain is an answer to retry with a fresh credential. Transparent, so the refusal keeps the chain’s own words: which link, until when, for which plane.

§

TaskClaim(ClaimError)

The worklist’s own protocol refused a claim or a decision.

Its own variant rather than a PolicyDenied, because no policy fired: the refusal is the claim protocol’s — four-eyes exclusion, a missing role, a task somebody else holds, an id that names nothing. Transparent, so the refusal keeps the store’s own words; typed, so a surface can answer honestly — “does not exist”, “not yours to decide” and “held by Bob” call for three different responses, and a class that flattens them teaches a caller to retry the permanent and abandon the transient.

§

ProposalWithheld

An approval was offered for a task whose proposal this plane cannot show.

Its own class, apart from a claim refusal and from PlanContract, because a caller does something different with it: decide from a plane that holds the key ring, or reject — a rejection of the unseen is safe and still records. Nothing was claimed or recorded, and the task stays open.

Fields

§task: String
§reason: Withheld
§

TaskChanged

A decision named a version of its task that is no longer the row’s.

Nothing was recorded, and no claim this call took is left behind. The remedy is to read the task again and decide on what it says now; the current version is deliberately not carried, so a caller cannot resubmit without reading.

Fields

§task: String
§

PlanContract(String)

§

UnknownTenant(String)

This process serves no plane for the tenant named.

Refused rather than defaulted, which is the whole point: a fallback plane would answer an unregistered tenant with somebody else’s data, and it would look exactly like working software.

§

ReservedEventKind

An event from outside named a kind this plane mints for itself.

A human task’s answer travels as an event in the agentplane. namespace, so accepting one from outside would let whoever may post an event decide a task. Refused at every intake; the worklist is the one door into the namespace.

Fields

§kind: String
§

PolicyBundleChanged

An open run would continue under policy semantics other than the bundle recorded at admission.

Journaled as the run’s quarantine reason rather than raised, so the message is the one a person reads off the run, and it names the verbs that answer it.

Fields

§recorded: Option<Digest>
§configured: Option<Digest>
§

DeclarationChanged

An open run would continue under a different declaration than the one it was admitted under.

The bundle above covers who may authorize; this covers what the agent is. A declarative agent’s behaviour is its manifest — the prompt, the tool grants, the model, the ceilings — so editing it and resuming runs one program over another’s journal. Refused before anything replays, which is the difference between a named remedy and discovering the same fact as a key mismatch several effects in.

Reported only where both sides name a declaration. A coded skill’s behaviour is the embedder’s binary, which this crate cannot identify and does not claim to; there, divergence is the answer, later and less precisely.

Journaled as the run’s quarantine reason rather than raised, as the bundle refusal is.

Fields

§agent: String
§recorded: Digest
§configured: Digest
§

DeclarationPinMismatch

A run pinned to one declaration revision was offered to a plane where another governs its capability — or none does.

Refused at admission, before authorization and reservation, so nothing is recorded: the caller reviewed one revision and this plane would run another.

Fields

§agent: String
§expected: Digest
§

SubjectUnbound

A data-subject binding the run’s declaration names resolved to nothing.

Refused at admission, before the run’s records are written: a run whose declaration says whose data it takes in, and which could not say it, would be traced to nobody.

Fields

§binding: String
§reason: String
§

CanonicalizationChanged

The history was written under a different canonicalization rule.

Not a divergence, and reporting it as one is the defect this exists to remove: every effect key comes out of the canonicalizer, so a rule change moves all of them at once and a healthy run replays as non-determinism. The run is unverifiable by this build, which is a different claim and the one the evidence supports.

The journal chain is unaffected — it hashes the bytes it stored rather than re-canonicalizing them — so the history is intact and readable; it simply cannot be re-derived here. Before format freeze the answer is to recreate; after it, a build that means to read old history implements the old rule and selects on this number.

Fields

§recorded: u16
§implemented: u16
§

PayloadsErased

The run’s own history is sealed to a key that was destroyed, so this build cannot read the plan it must replay.

A completed erasure, not a fault, and the two call for opposite responses — which is why this is its own variant rather than the deserialization error the payload’s shape produces. A sealed payload arrives at the parser as {"$sealed": "…"}, and the parser says what a parser says: a field is missing. An operator reading that goes looking for a corrupt journal, for a version skew, for a bug. The journal is intact, the chain still verifies, and nothing is wrong with the build: the data is gone because somebody asked for it to be.

What is still available is the part that matters. A run whose data is erased can never execute again — its recorded effects cannot be read back, so there is nothing to resume onto — but it can still be concluded. A cancellation and an abandonment are recorded in the clear and need no plan, so an operator is never left holding a run with no verb that clears it.

Fields

§

PayloadsSealed

The run’s history is sealed, and this plane holds no key ring to open it.

Not an erasure, and kept apart from PayloadsErased because the two send a reader opposite ways: erased says the data is gone for good, this says it is intact and this plane cannot read it — an operator’s terminal, a restored export, a verifier handed no key. A ring that is wired answers for itself: a destroyed key is an erasure, an unreachable one fails the read.

Fields

§

NoCaseStore

The run is bound to a case and this plane holds no case store, so what a resume wrote would sit outside the case.

About this plane, not the run: a plane with a case store continues it, so a caller holding a durable request — a stop, a delivered answer — leaves the driving to that plane.

Fields

§case: String
§

NoProvider

Nothing on this plane answers to the name run was given.

Carries what the plane does provide, because the question a reader has next is always “then what should I have asked for?” — and the plane is the only party that can answer it. A refusal that names the missing thing and not the available ones sends somebody back to their own source to reconstruct a list this error was already holding.

Fields

§target: String

The capability (or skill name) that was asked for.

§available: Vec<String>

Every capability this plane provides, sorted. Empty means no skills.

§

QuotaExceeded(QuotaError)

The tenant is at a ceiling, so nothing was admitted.

Distinct from a policy denial, because they call for opposite responses. A denial says you may not, and retrying is pointless. A quota refusal says not right now, and the caller should come back — a concurrency ceiling clears when a run finishes. Collapsing them would teach callers to retry denials or to give up on back-pressure. Transparent, because the variant carries a halt as well as a ceiling and the two must not share a prefix: an operator reading quota: … is halted has been told a stop is back-pressure, which is the confusion QuotaError::Halted exists to prevent.

§

Draining

This instance is shutting down, so nothing was admitted.

Back-pressure, not a verdict: the work is fine and another instance will take it. Kept apart from a quota refusal because the two clear on different terms — a ceiling clears when a run finishes here, this one clears when the caller reaches a different process — and apart from a halt, which means stop asking anybody.

Nothing was written: no lease, no quota slot, no journal. A caller may retry immediately, elsewhere.

§

QuotaSettlementPending

A live pass finished, but its durable quota receipt did not commit.

The run deliberately keeps its lease. Once it expires, the abandonment sweep derives the same settlement from the journal and retries it under the idempotent (run, epoch) key; releasing here would remove that retry handle and turn a store outage into permanent under-accounting.

Fields

§epoch: u64
§detail: String
§

ChainBroken

The journal’s hash chain does not verify. Either a record was altered after the fact, or a writer produced bytes it did not hash.

Fields

§seq: Seq
§detail: String
§

Fenced

A write was rejected because another instance owns this run at a higher epoch. Not an error to retry blindly: this instance has been fenced and must drop the run.

Fields

§held: u64
§current: u64
§

LeaseHeld

Another instance holds a live lease on this run. Retryable after the lease expires — unlike Fenced, which never is.

Fields

§owner: String
§remaining_secs: u64
§

NotQuarantined

An operator’s answer was offered to a run that is not asking a question.

Reopening and abandoning are answers to a quarantine specifically, and a run in any other state has either not stopped, stopped for a reason a resume already addresses, or ended. Refused by name rather than recorded and ignored: an intervention that is acknowledged and then not acted on is worse than one that is declined, because the operator stops looking.

Fields

§status: String
§

NotUndecided

An assertion was offered about an effect whose outcome is already known.

A person may supply the fact the journal lacks; they may not replace one it holds. Overwriting a recorded landing with “it did not happen” would let an operator talk a run out of compensating work that stands in the world — with the record showing an orderly reconciliation.

Fields

§effect: String
§

CannotUnwind

Something that unwinds was asked for on a run that must not unwind.

Cancelling promises to reverse what the run did and put the world back, which is exactly what a run holding an unknown outcome may not do. Its own variant rather than a generic refusal, because the operator’s next move is named in it and a caller matching on the class should be able to route them there.

Fields

§

AlreadyConcluded

A cancellation was asked of a run that has already concluded.

Refused rather than recorded: a sealed run is not reopened by anybody changing their mind, and a stored request against it would answer the operator “recorded” for a stop that can never happen.

Fields

§outcome: String
§

ControlStands

An operator’s lift or release was recorded, and the control it ended still stands.

The record is written before the register row goes, and the two share no transaction. Its own variant rather than a store failure, because the record exists: run names it, and acting again writes a second.

Fields

§detail: String
§

Store(StoreError)

§

Encoding(Error)

Implementations§

Source§

impl RuntimeError

Source

pub fn from_store(e: StoreError) -> Self

Lift a store error into the operator-facing taxonomy.

Two promotions matter, because both change what a human should do:

  • Fenced — “I lost ownership of this run” (drop it; another instance has it), as opposed to “the database is unhappy” (retry).
  • Corrupt → ChainBroken — the journal does not verify. That is never a retryable storage hiccup; it means the history has been altered and nothing downstream of it can be trusted. Leaving it as a generic store error would bury the one failure that must never be shrugged off.

Trait Implementations§

Source§

impl Debug for RuntimeError

Source§

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

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

impl Display for RuntimeError

Source§

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

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

impl Error for RuntimeError

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<ClaimError> for RuntimeError

Source§

fn from(source: ClaimError) -> Self

Converts to this type from the input type.
Source§

impl From<DelegationError> for RuntimeError

Source§

fn from(source: DelegationError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for RuntimeError

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.
Source§

impl From<PolicyError> for RuntimeError

Source§

fn from(source: PolicyError) -> Self

Converts to this type from the input type.
Source§

impl From<QuotaError> for RuntimeError

Source§

fn from(source: QuotaError) -> Self

Converts to this type from the input type.
Source§

impl From<StoreError> for RuntimeError

Source§

fn from(source: StoreError) -> 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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
Source§

impl<T> MaybeSend for T
where T: Send,

Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

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

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 = !

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

fn try_from(value: U) -> Result<T, !>

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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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