Skip to main content

EngineError

Enum EngineError 

Source
pub enum EngineError {
Show 62 variants MissingStore, MissingStopDrainTimeout, ZeroStopDrainTimeout, MissingVisibilityStore, Load { reason: String, }, UnenforceableContract { workflow_type: String, count: usize, detail: String, }, UnknownVersion { workflow_type: String, version: ContentHash, loaded: String, }, VersionPinned { workflow_type: String, version: ContentHash, pinned_by: PinHolder, }, RouteActive { workflow_type: String, version: ContentHash, }, ManifestMismatch { workflow_type: String, version: ContentHash, resident_digest: String, incoming_digest: String, }, ConflictingEventPublisher, EventStreaming(PublishError), Store(StoreError), Durability(DurabilityError), Package(PackageError), ContractIdentity { workflow_type: String, source: ContractIdentityError, }, NoQueueDeclaration { workflow_type: String, version: ContentHash, activities: String, }, StartInputRefused { workflow_type: String, version: ContentHash, reason: String, }, SignalRefused { workflow_id: WorkflowId, run_id: RunId, signal_name: String, version: ContentHash, reason: String, }, Runtime { reason: String, }, Gate3BifReplacementMissing { module: String, function: String, arity: u8, }, StartupRecoveryNotDeferred, StartupRecoveryAlreadyRan, StartupCatchupBeforeWorkflowRecovery, StartupRecoverySlotPoisoned, CleanupExecutorPoisoned, CleanupExecutorShutdownTimedOut { timeout_millis: u128, since_progress_millis: u128, queued: usize, }, ProcessExitRegistryPoisoned, ProcessExitOwnershipPoisoned { process_id: u64, }, ProcessExitStatePoisoned { process_id: u64, }, ProcessExitSubscriptionUnavailable, ProcessExitDrainerSpawn { reason: String, }, ProcessExitDrainerPoisoned, ProcessExitOutcomeMissingAfterEvent { process_id: u64, }, ProcessExitEventStreamDisconnected, ProcessExitDrainerShutdownTimedOut { timeout_millis: u128, since_progress_millis: u128, queued: usize, }, ProcessExitDrainerPanicked, ProcessExitCallbackDispatcherPoisoned, ProcessExitCallbackDispatcherUnavailable, ProcessExitCallbackDispatcherShutdownTimedOut { timeout_millis: u128, since_progress_millis: u128, queued: usize, }, ProcessExitAlreadyTerminal { process_id: u64, }, ActivityDeliveryPoisoned { process_id: u64, }, RegistryPoisoned, RunNotInHistory { workflow_id: WorkflowId, run_id: RunId, }, CatalogPoisoned, InvalidState { reason: String, }, ShuttingDown, ActivityLeaseAfterTerminal { workflow_id: WorkflowId, run_id: RunId, activity_id: ActivityId, attempt: u32, }, WorkflowNotFound { workflow_type: String, }, TerminalWriterUnavailable { workflow_id: String, run_id: String, holder: String, }, TerminalWriterHeld { workflow_id: String, run_id: String, }, WorkflowWriterHeld { workflow_id: String, holder_run_id: String, holder_pid: u64, }, WorkflowIdAlreadyLive { workflow_id: String, holder_run_id: String, holder_pid: u64, }, WorkflowWritersAmbiguous { workflow_id: String, runs: String, }, EngineTaskEpochClosed { workflow_id: String, run_id: String, }, RunIsRecoverable { workflow_id: String, run_id: String, version: String, }, NoResidencyVerdict { workflow_id: String, run_id: String, }, ScheduleNotFound { schedule_id: ScheduleId, }, Schedule { reason: String, }, NifRegistration { reason: String, }, SignalRouter(SignalRouterError), Query(QueryError),
}
Expand description

Errors returned by the embedded workflow engine.

Variants§

§

MissingStore

The builder was asked to construct an engine without an event store.

§

MissingStopDrainTimeout

The builder was asked to construct an engine without a stop-drain bound. The engine invents no patience of its own (AE-017): the value is the operator’s, handed down from the server’s configuration.

§

ZeroStopDrainTimeout

The runtime was handed a zero stop-drain bound. Zero would fail every stop the instant a callback was in flight — the opposite of a bound.

§

MissingVisibilityStore

The builder was asked to construct an engine without a visibility store.

§

Load

A workflow package failed to load or validate for engine registration.

Fields

§reason: String

Human-readable load failure reason.

§

UnenforceableContract

A package offered for deployment declares a contract the engine cannot enforce: at least one declared schema does not compile into a validator.

Refused at the door rather than admitted, because the alternative is silent: every admission boundary answers an uncompilable schema by letting the value through unchecked, so a package that reaches the catalog with one runs with that part of its declared contract switched off and only a log line to say so.

Fields

§workflow_type: String

Logical workflow type of the refused package.

§count: usize

How many declarations could not be compiled.

§detail: String

Each unenforceable declaration, named, with the compiler’s reason.

§

UnknownVersion

A route or unload targeted a (workflow type, version) that is not loaded.

Fields

§workflow_type: String

Logical workflow type requested by the caller.

§version: ContentHash

Content-hash version requested by the caller.

§loaded: String

Comma-separated loaded versions of the type, or none.

§

VersionPinned

An unload was refused because something still pins the version.

Fields

§workflow_type: String

Logical workflow type targeted by the unload.

§version: ContentHash

Content-hash version targeted by the unload.

§pinned_by: PinHolder

What pins the version, naming the concrete holder.

§

RouteActive

An unload was refused because the version is route-active for its type.

Fields

§workflow_type: String

Logical workflow type targeted by the unload.

§version: ContentHash

Content-hash version targeted by the unload.

§

ManifestMismatch

An idempotent re-load presented the resident package identity with a different manifest. V4 binds beams and the durable execution contract, but not every packaging/admin field, so this remains the wrong-deploy tripwire: the resident version is retained and the archive is refused.

Fields

§workflow_type: String

Logical workflow type targeted by the load.

§version: ContentHash

Content-hash version shared by both archives.

§resident_digest: String

Canonical digest of the resident manifest.

§incoming_digest: String

Canonical digest of the incoming manifest.

§

ConflictingEventPublisher

The builder was given both event_streaming and an explicit event-publisher seam.

§

EventStreaming(PublishError)

Live event streaming setup failed.

§

Store(StoreError)

The configured event store returned an error.

§

Durability(DurabilityError)

The durability recorder or replay path returned an error.

§

Package(PackageError)

A .aion package operation returned an error.

§

ContractIdentity

The selected package identity predates the .v4 contract commitment.

Fields

§workflow_type: String

Workflow type selected for the start.

§source: ContractIdentityError

Typed migration refusal from the package identity boundary.

§

NoQueueDeclaration

The package names activities without a durable queue-scoped contract.

Fields

§workflow_type: String

Workflow type selected for the start.

§version: ContentHash

Exact .v4 package identity selected for the run.

§activities: String

Stable comma-separated unscoped activity names.

§

StartInputRefused

A start’s input did not satisfy the declared input schema of the exact package identity the start resolved to.

Returned at the start boundary BEFORE any history is appended and before any process is spawned, so a refused start leaves no trace: the caller sees their own mistake at the moment they made it, with nothing to clean up.

Fields

§workflow_type: String

Workflow type selected for the start.

§version: ContentHash

Exact .v4 package identity the start resolved to.

§reason: String

What did not match, naming every field that failed.

§

SignalRefused

A signal was refused at the boundary: its name is not declared by the target run’s package, or its payload did not satisfy the declared payload type.

Returned BEFORE anything is recorded and before the arrival can be consumed, so the target run’s history is unchanged and it stays parked on exactly the wait it was parked on. That ordering is the whole point: a signal decoded after being consumed destroys a durable run that a refusal merely inconveniences.

Fields

§workflow_id: WorkflowId

Workflow execution the signal targeted.

§run_id: RunId

Concrete run the signal targeted.

§signal_name: String

Signal name the caller sent.

§version: ContentHash

Exact .v4 package identity the target run is pinned to.

§reason: String

Why the signal was refused — an undeclared name, or the fields of the payload that did not match the declared type.

§

Runtime

The embedded runtime returned an error.

Fields

§reason: String

Human-readable runtime failure reason.

§

Gate3BifReplacementMissing

A Gate-3 BIF required for tracked local fun spawns was not registered.

Fields

§module: String

Native module containing the required function.

§function: String

Required native function.

§arity: u8

Required native function arity.

§

StartupRecoveryNotDeferred

crate::Engine::run_startup_recovery was called on an engine whose build was not deferred — build() already ran startup recovery, and running it twice would re-dispatch every in-flight activity.

§

StartupRecoveryAlreadyRan

crate::Engine::run_startup_recovery was called a second time.

§

StartupCatchupBeforeWorkflowRecovery

crate::Engine::run_startup_catchup was called before the workflow-recovery leg ran — catch-up delivers owed timer fires to resident workflows, so residency recovery must precede it.

§

StartupRecoverySlotPoisoned

The deferred-startup-recovery slot lock was poisoned.

§

CleanupExecutorPoisoned

The runtime-owned cleanup executor’s ownership state was poisoned.

§

CleanupExecutorShutdownTimedOut

The runtime cleanup worker did not stop within the configured bound.

Fields

§timeout_millis: u128

The no-progress bound the drain waited under, in milliseconds.

§since_progress_millis: u128

How long the worker had completed nothing when the drain gave up.

§queued: usize

Jobs still queued behind the one in flight.

§

ProcessExitRegistryPoisoned

The process-exit registry lifecycle lock was poisoned.

§

ProcessExitOwnershipPoisoned

A process exit record’s installation/abort ownership gate was poisoned.

Fields

§process_id: u64

Process whose monitor/abort ownership could not be serialized.

§

ProcessExitStatePoisoned

A process exit record’s fan-out state was poisoned.

Fields

§process_id: u64

Process whose cached exit state could not be accessed.

§

ProcessExitSubscriptionUnavailable

The scheduler’s one exit-event subscription was already claimed.

§

ProcessExitDrainerSpawn

The singleton process-exit drainer could not be spawned.

Fields

§reason: String

Operating-system thread creation failure.

§

ProcessExitDrainerPoisoned

The singleton process-exit drainer’s ownership lock was poisoned.

§

ProcessExitOutcomeMissingAfterEvent

beamr published an exit event without the promised durable outcome.

Fields

§process_id: u64

Process named by the contract-breaking event.

§

ProcessExitEventStreamDisconnected

beamr disconnected its event publisher while the runtime still owned it.

§

ProcessExitDrainerShutdownTimedOut

The process-exit drainer did not stop within the configured bound.

Fields

§timeout_millis: u128

The no-progress bound the drain waited under, in milliseconds.

§since_progress_millis: u128

How long the worker had completed nothing when the drain gave up.

§queued: usize

Jobs still queued behind the one in flight.

§

ProcessExitDrainerPanicked

The process-exit drainer thread panicked.

§

ProcessExitCallbackDispatcherPoisoned

The process-exit callback dispatcher’s ownership state was poisoned.

§

ProcessExitCallbackDispatcherUnavailable

The process-exit callback dispatcher had already stopped.

§

ProcessExitCallbackDispatcherShutdownTimedOut

The process-exit callback dispatcher did not stop within its configured bound.

Fields

§timeout_millis: u128

The no-progress bound the drain waited under, in milliseconds.

§since_progress_millis: u128

How long the worker had completed nothing when the drain gave up.

§queued: usize

Jobs still queued behind the one in flight.

§

ProcessExitAlreadyTerminal

A retired process generation cannot accept another outcome consumer.

Fields

§process_id: u64

Process generation whose heavyweight exit record was retired.

§

ActivityDeliveryPoisoned

A workflow’s activity-delivery synchronization lock was poisoned.

Fields

§process_id: u64

Workflow process whose scoped delivery lock was poisoned.

§

RegistryPoisoned

The active workflow registry lock was poisoned.

§

RunNotInHistory

A registered run has no WorkflowStarted in the history it was reconciled against — the registry and the store disagree that it exists.

Raised by registry reconciliation rather than defaulting the projection. status_from_events returns Running for a slice holding no lifecycle event, so a run absent from the history it is projected against would otherwise be silently cached as RUNNING — a terminal run reported live, produced by the reconciliation whose whole job is to stop exactly that.

Not reachable through a normal start: WorkflowStarted is recorded before the handle is published. It means a genuine invariant breach, so it is surfaced rather than absorbed.

Fields

§workflow_id: WorkflowId

Workflow whose history was read.

§run_id: RunId

Run that the history does not contain.

§

CatalogPoisoned

The workflow catalog lock was poisoned.

§

InvalidState

A precondition on the target workflow’s current state was not met.

Raised by the reopen operation when the target run is not in a reopenable state: not terminal, terminal for a non-reopenable reason (Completed/TimedOut), or already Running. The reason names the actual status so callers and operators can see why the reopen was rejected. Maps to the INVALID_STATE wire code (gRPC FailedPrecondition / HTTP 409).

Fields

§reason: String

Human-readable precondition-failure reason naming the actual status.

§

ShuttingDown

The engine is already shutting down and no new workflow starts are accepted.

§

ActivityLeaseAfterTerminal

A worker’s lease of an activity attempt arrived after the run’s terminal event, so there is no open attempt for it to attribute.

Nothing is recorded: appending behind a terminal would put a fact about an attempt into a lease segment that has already closed. The caller (the server’s handoff seam) logs and counts it; the completion that closed the run stands.

Fields

§workflow_id: WorkflowId

Workflow whose run had already terminated.

§run_id: RunId

The terminated run.

§activity_id: ActivityId

Ordinal of the activity the lease named.

§attempt: u32

One-based attempt the lease named.

§

WorkflowNotFound

No live, durable, or loaded workflow was found for the request.

Fields

§workflow_type: String

Logical workflow type requested by the caller.

§

TerminalWriterUnavailable

A terminal-writer reservation could not be taken because the workflow already has a writer (#117(c)).

The extraordinary cancellation path exists only for a run that can never obtain a handle. A workflow that has one — or that another reservation is already writing — is not that case, and taking a second writer would break the single-writer invariant this refusal protects.

Fields

§workflow_id: String

Workflow whose writer slot is occupied.

§run_id: String

Run the refused reservation named.

§holder: String

What holds the slot, in the operator’s terms.

§

TerminalWriterHeld

A handle could not be registered because a terminal-writer reservation holds this workflow’s writer slot (#117(c)).

The mirror of Self::TerminalWriterUnavailable, and transient by construction: a reservation lives only across one terminal transition.

Fields

§workflow_id: String

Workflow whose writer slot is reserved.

§run_id: String

Run holding the reservation.

§

WorkflowWriterHeld

A caller asked to register the SOLE handle for a workflow while another run of that workflow already held one.

Distinct from Self::TerminalWriterHeld, which reports a reservation rather than a live process, and from an ordinary insert, which deliberately replaces. A Recorder writes the WORKFLOW’s event stream, so a handle on any run of the same workflow is a second writer (invariant #3) — this is what a caller receives when it demanded to be the only one and was not.

Fields

§workflow_id: String

Workflow that already has a writer.

§holder_run_id: String

Run holding the live handle.

§holder_pid: u64

Process backing the incumbent handle.

§

WorkflowIdAlreadyLive

A start was asked to seed a FRESH recorder for a workflow id that already has a live handle (aion#213).

The start path derives a new recorder’s sequence head from an UNLOCKED history read. That read is only sound for an id nothing is writing: a workflow that already has a registered handle has a recorder that owns its head, and seeding a second one from a store read produces two writers for one history — the double-writer this refusal exists to stop. A continuation (continue-as-new, a workloop generation) must therefore go through the incumbent recorder rather than re-seed, and a caller that genuinely meant a fresh execution must choose an unused id.

Fields

§workflow_id: String

Workflow id the start requested.

§holder_run_id: String

Run whose handle already holds the workflow’s recorder.

§holder_pid: u64

Process backing the incumbent handle.

§

WorkflowWritersAmbiguous

Two or more live handles were found for one workflow id (aion#213).

A Recorder writes the WORKFLOW’s event stream, so exactly one handle may exist per workflow id (invariant 3). A resolver that found several reports this instead of picking one: picking the first would route a durable append through whichever handle a HashMap iteration happened to yield, which is how a second writer stays invisible.

Fields

§workflow_id: String

Workflow with more than one live handle.

§runs: String

The runs holding the competing handles, comma separated.

§

EngineTaskEpochClosed

A terminal event was about to be appended after the engine-task epoch had already closed.

Raised at the append boundary itself, which is the only instant at which the hazard it guards is real. The engine that owned this run has been shut down or released, so this process is no longer that workflow’s single writer (invariant 3). Appending here risks two writers.

§This is not only the successor case

The obvious reading — a successor engine is already recovering the same history — is the eventual case, not the whole of it. Engine::shutdown closes the epoch as its FIRST act and only stops admitting process-exit callbacks several steps later, so this error is also raised for runs that exit during this engine’s own graceful teardown, while no successor exists yet. Saying “a successor may already be recovering” would tell an operator reading the message during a clean shutdown to go looking for a second node that is not there.

Deliberately not transient: no later attempt re-opens a closed epoch. In both cases the run stays Running and a startup sweep — the successor’s, or this node’s own on restart — re-installs a monitor, which is the mechanism that actually repairs it.

Fields

§workflow_id: String

Workflow whose terminal event was refused.

§run_id: String

Run whose terminal event was refused.

§

RunIsRecoverable

The extraordinary cancellation path was asked for a run whose pinned package resolves right now, so the run is recoverable (#117(c)).

Measured at the moment of the request, never cited from an earlier boot’s verdict: a redeploy between then and now is exactly the remedy that makes the ordinary path work again, and the ordinary path must be used when it does.

Fields

§workflow_id: String

Workflow the request named.

§run_id: String

Run the request named.

§version: String

The pinned package version that resolved.

§

NoResidencyVerdict

A run holds no handle, cannot obtain one, and this engine has no recorded reason why (#117(c)).

Distinct from Self::WorkflowNotFound on purpose: the run EXISTS and its history is readable. What is absent is a verdict from this process’s startup recovery, so the extraordinary cancellation path — which must cite that verdict — has nothing to cite.

Fields

§workflow_id: String

Workflow the request named.

§run_id: String

Run the request named.

§

ScheduleNotFound

No durable schedule was found for the request.

Fields

§schedule_id: ScheduleId

Schedule identifier requested by the caller.

§

Schedule

Schedule trigger, projection, or evaluator side effect failed.

Fields

§reason: String

Human-readable schedule failure reason.

§

NifRegistration

Native implemented function registration failed.

Fields

§reason: String

Human-readable native implemented function registration failure reason.

§

SignalRouter(SignalRouterError)

Signal routing failed after the target was resolved.

§

Query(QueryError)

Live workflow query dispatch failed after the target was resolved.

Trait Implementations§

Source§

impl Debug for EngineError

Source§

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

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

impl Display for EngineError

Source§

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

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

impl Error for EngineError

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<DurabilityError> for EngineError

Source§

fn from(source: DurabilityError) -> Self

Converts to this type from the input type.
Source§

impl From<PackageError> for EngineError

Source§

fn from(source: PackageError) -> Self

Converts to this type from the input type.
Source§

impl From<PublishError> for EngineError

Source§

fn from(source: PublishError) -> Self

Converts to this type from the input type.
Source§

impl From<QueryError> for EngineError

Source§

fn from(source: QueryError) -> Self

Converts to this type from the input type.
Source§

impl From<ScheduleError> for EngineError

Source§

fn from(error: ScheduleError) -> Self

Converts to this type from the input type.
Source§

impl From<ScheduleEvaluatorError> for EngineError

Source§

fn from(error: ScheduleEvaluatorError) -> Self

Converts to this type from the input type.
Source§

impl From<SignalRouterError> for EngineError

Source§

fn from(source: SignalRouterError) -> Self

Converts to this type from the input type.
Source§

impl From<StoreError> for EngineError

Source§

fn from(source: StoreError) -> Self

Converts to this type from the input type.
Source§

impl From<WorkloopError> for EngineError

Source§

fn from(error: WorkloopError) -> 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> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. 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> 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