Skip to main content

ScriptError

Enum ScriptError 

Source
#[non_exhaustive]
pub enum ScriptError {
Show 92 variants StaleLease, LeaseExpired, LeaseRevoked, ExecutionNotActive { terminal_outcome: String, lease_epoch: String, lifecycle_phase: String, attempt_id: String, }, NoActiveLease, FenceRequired, PartialFenceTriple, ActiveAttemptExists, UseClaimResumedExecution, NotAResumedExecution, ExecutionNotLeaseable, LeaseConflict, InvalidClaimGrant, ClaimGrantExpired, NoEligibleExecution, BudgetExceeded, BudgetSoftExceeded, ExecutionNotSuspended, AlreadySuspended, WaitpointClosed, WaitpointNotFound, TargetNotSignalable, WaitpointPendingUseBufferScript, DuplicateSignal, PayloadTooLarge, SignalLimitExceeded, InvalidWaitpointKey, InvalidToken, InvalidLeaseForSuspend, ResumeConditionNotMet, WaitpointNotPending, PendingWaitpointExpired, InvalidWaitpointForExecution, WaitpointAlreadyExists, WaitpointNotOpen, ExecutionNotTerminal, MaxReplaysExhausted, StreamClosed, StaleOwnerCannotAppend, RetentionLimitExceeded, ExecutionNotEligible, ExecutionNotInEligibleSet, GrantAlreadyExists, ExecutionNotReclaimable, InvalidDependency, StaleGraphRevision, ExecutionAlreadyInFlow, CycleDetected, FlowNotFound, ExecutionNotInFlow, DependencyAlreadyExists, SelfReferencingEdge, FlowAlreadyTerminal, DepsNotSatisfied, NotBlockedByDeps, NotRunnable, Terminal, InvalidBlockingReason, OkAlreadyApplied, AttemptNotFound, AttemptNotInCreatedState, AttemptNotStarted, AttemptAlreadyTerminal, ExecutionNotFound, ExecutionNotEligibleForAttempt, ReplayNotAllowed, MaxRetriesExhausted, StreamNotFound, StreamAlreadyClosed, InvalidFrameType, InvalidOffset, Unauthorized, BudgetNotFound, InvalidBudgetScope, BudgetAttachConflict, BudgetOverrideNotAllowed, QuotaPolicyNotFound, RateLimitExceeded, ConcurrencyLimitExceeded, QuotaAttachConflict, InvalidQuotaSpec, InvalidInput(String), CapabilityMismatch(String), InvalidCapabilities(String), InvalidPolicyJson(String), WaitpointNotTokenBound, InvalidKid, InvalidSecretHex, InvalidGraceMs, RotationConflict(String), InvalidTagKey(String), Parse { fcall: String, execution_id: Option<String>, message: String, },
}
Expand description

All error codes returned by FlowFabric Valkey Functions. Matches RFC-010 §10.7 exactly.

Does not derive Serialize/Deserialize/PartialEq/Eq/Hash because the Valkey variant wraps ferriskey::Error, which implements none of those. Call sites compare via matches!/.class() rather than ==, so this is not a regression.

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.
§

StaleLease

Stop. Lease superseded by reclaim.

§

LeaseExpired

Stop. Lease TTL elapsed.

§

LeaseRevoked

Stop. Operator revoked.

§

ExecutionNotActive

Execution is not in active state. Carries enriched detail so the SDK can reconcile a replay of a terminal operation after a network drop: if terminal_outcome matches what the caller attempted AND lease_epoch matches their lease, the prior call committed and the retry should be treated as a successful replay. lifecycle_phase distinguishes terminal from runnable (retry-scheduled). attempt_id is the per-attempt replay guard (preserved on terminal, cleared on retry).

Fields

§terminal_outcome: String
§lease_epoch: String
§lifecycle_phase: String
§attempt_id: String
§

NoActiveLease

Revoke target has no active lease (already revoked/expired/unowned).

§

FenceRequired

RFC #58.5: a lease-bound FCALL was invoked with an empty (lease_id, lease_epoch, attempt_id) triple and the caller is not an allowlisted operator override. Worker-path callers must always pass the fence triple; unfenced callers must supply source == "operator_override" (terminal ops) or use a different FCALL (renew / suspend hard-reject with no override path). TERMINAL: the caller is structurally incorrect; retrying without a fence will not help.

§

PartialFenceTriple

RFC #58.5: the fence triple arrived with some but not all three fields populated. Programming error — either all of (lease_id, lease_epoch, attempt_id) must be set, or all three must be empty. TERMINAL.

§

ActiveAttemptExists

Bug. Active attempt already exists.

§

UseClaimResumedExecution

Re-dispatch to claim_resumed_execution.

§

NotAResumedExecution

Re-dispatch to claim_execution.

§

ExecutionNotLeaseable

State changed since grant. Request new grant.

§

LeaseConflict

Another worker holds lease. Request different execution.

§

InvalidClaimGrant

Grant missing/mismatched. Request new grant.

§

ClaimGrantExpired

Grant TTL elapsed. Request new grant.

§

NoEligibleExecution

Backoff 100ms-1s, retry.

§

BudgetExceeded

Immediate stop. Call fail_execution(budget_exceeded).

§

BudgetSoftExceeded

Log warning. Continue.

§

ExecutionNotSuspended

Already resumed/cancelled. No-op.

§

AlreadySuspended

Open suspension exists. No-op.

§

WaitpointClosed

Signal too late. Return to caller.

§

WaitpointNotFound

Waitpoint may not exist yet. Retry with backoff.

§

TargetNotSignalable

Execution not suspended, no pending waitpoint.

§

WaitpointPendingUseBufferScript

Route to buffer_signal_for_pending_waitpoint.

§

DuplicateSignal

Dedup. Return existing signal_id.

§

PayloadTooLarge

Payload > 64KB.

§

SignalLimitExceeded

Max signals reached.

§

InvalidWaitpointKey

MAC failed on the waitpoint_key field itself (structural mismatch against the stored binding).

§

InvalidToken

MAC failed on the HMAC waitpoint_token bearer credential (signal-delivery path). Distinct from Self::InvalidWaitpointKey because the operator-surfaced error code is different — callers typically render the Lua code verbatim in 4xx response bodies.

§

InvalidLeaseForSuspend

Invalid lease for suspend.

§

ResumeConditionNotMet

Conditions not satisfied.

§

WaitpointNotPending

Waitpoint not in pending state.

§

PendingWaitpointExpired

Pending waitpoint expired before suspension committed.

§

InvalidWaitpointForExecution

Waitpoint/execution binding mismatch.

§

WaitpointAlreadyExists

Waitpoint already exists (pending or active).

§

WaitpointNotOpen

Waitpoint not in an open state.

§

ExecutionNotTerminal

Cannot replay non-terminal.

§

MaxReplaysExhausted

Replay limit reached.

§

StreamClosed

Attempt terminal. No appends.

§

StaleOwnerCannotAppend

Lease mismatch on stream append.

§

RetentionLimitExceeded

Frame > 64KB.

§

ExecutionNotEligible

State changed. Scheduler skips.

§

ExecutionNotInEligibleSet

Another scheduler got it. Skip.

§

GrantAlreadyExists

Grant already issued. Skip.

§

ExecutionNotReclaimable

Already reclaimed/cancelled. Skip.

§

InvalidDependency

Edge doesn’t exist.

§

StaleGraphRevision

Re-read adjacency, retry.

§

ExecutionAlreadyInFlow

Already in another flow.

§

CycleDetected

Edge would create cycle.

§

FlowNotFound

Flow does not exist.

§

ExecutionNotInFlow

Execution is not a member of the specified flow.

§

DependencyAlreadyExists

Dependency edge already exists.

§

SelfReferencingEdge

Self-referencing edge (upstream == downstream).

§

FlowAlreadyTerminal

Flow is already in a terminal state (cancelled/completed/failed).

§

DepsNotSatisfied

Dependencies not yet satisfied (for promote_blocked_to_eligible).

§

NotBlockedByDeps

Not blocked by dependencies (for promote/unblock).

§

NotRunnable

Execution not runnable (for block/unblock/promote).

§

Terminal

Execution is terminal (for block/promote).

§

InvalidBlockingReason

Invalid blocking reason for block_execution_for_admission.

§

OkAlreadyApplied

Usage seq already processed. No-op.

§

AttemptNotFound

Attempt index doesn’t exist.

§

AttemptNotInCreatedState

Attempt not created. Internal sequencing error.

§

AttemptNotStarted

Attempt not running.

§

AttemptAlreadyTerminal

Already ended. No-op.

§

ExecutionNotFound

Execution doesn’t exist.

§

ExecutionNotEligibleForAttempt

Wrong state for new attempt.

§

ReplayNotAllowed

Not terminal or limit reached.

§

MaxRetriesExhausted

Retry limit reached.

§

StreamNotFound

No frames appended yet. Normal for new attempts.

§

StreamAlreadyClosed

Already closed. No-op.

§

InvalidFrameType

Unrecognized frame type.

§

InvalidOffset

Invalid Stream ID.

§

Unauthorized

Auth failed.

§

BudgetNotFound

Budget doesn’t exist.

§

InvalidBudgetScope

Malformed scope.

§

BudgetAttachConflict

Budget already attached or conflicts.

§

BudgetOverrideNotAllowed

No operator privileges.

§

QuotaPolicyNotFound

Quota doesn’t exist.

§

RateLimitExceeded

Window full. Backoff retry_after_ms.

§

ConcurrencyLimitExceeded

Concurrency cap hit.

§

QuotaAttachConflict

Quota already attached.

§

InvalidQuotaSpec

Malformed quota definition.

§

InvalidInput(String)

Caller supplied a non-numeric value where a number is required.

§

CapabilityMismatch(String)

Worker caps do not satisfy execution’s required_capabilities. Payload is the sorted-CSV of missing tokens. RETRYABLE: execution stays in the eligible ZSET for a worker with matching caps.

§

InvalidCapabilities(String)

Caller supplied a malformed or oversized capability list (defense against 1MB-repeated-token payloads). TERMINAL from this call’s perspective: the caller must fix its config before retrying.

§

InvalidPolicyJson(String)

ff_create_execution received a policy_json that is not valid JSON or whose routing_requirements is structurally wrong (not an object, required_capabilities not an array). TERMINAL: the submitter must send a well-formed policy. Kept distinct from invalid_capabilities so tooling can distinguish “payload never parsed” from “payload parsed but contents rejected”.

§

WaitpointNotTokenBound

Pending waitpoint record is missing its HMAC token field. Returned by ff_suspend_execution when activating a pending waitpoint whose waitpoint_token field is absent or empty (pre-HMAC-upgrade record or a corrupted write). Surfacing this at activation time instead of letting every subsequent signal delivery silently reject with missing_token makes the degraded state visible at the right step. TERMINAL: the pending waitpoint is unrecoverable without a fresh one.

§

InvalidKid

Rotation FCALL: new_kid empty or contains :.

§

InvalidSecretHex

Rotation FCALL: new_secret_hex empty, odd length, or non-hex.

§

InvalidGraceMs

Rotation FCALL: grace_ms not a non-negative integer.

§

RotationConflict(String)

Rotation FCALL: same kid already installed with a different secret. Carries the kid so operators see which one conflicted. Refuse — the operator must pick a fresh kid or restore the stored secret.

§

InvalidTagKey(String)

ff_set_execution_tags / ff_set_flow_tags received a tag key that does not match the reserved namespace ^[a-z][a-z0-9_]*\.. Callers must prefix tag keys with <caller>. (e.g. cairn.task_id). TERMINAL: caller must fix input before retry. Payload is the offending key for precise diagnostics.

§

Parse

Failed to parse FCALL return value. fcall names the FCALL OR the nearest semantic parser (e.g. "parse_report_usage_result", "stream_tail_decode", "decode_flow_snapshot"). Never empty. execution_id is populated at sites where the exec_id is in scope (the 13 task.rs sites) and None elsewhere. message carries expected-vs-got detail.

Fields

§fcall: String
§execution_id: Option<String>
§message: String

Implementations§

Source§

impl ScriptError

Source

pub fn class(&self) -> ErrorClass

Classify this error for SDK action dispatch.

Source

pub fn from_code(code: &str) -> Option<Self>

Parse an error code string (from Lua return) into a ScriptError.

Source

pub fn from_code_with_detail(code: &str, detail: &str) -> Option<Self>

Like from_code, but preserves the Lua-side detail payload for variants that carry a String. Lua returns {0, code, detail} for capability_mismatch (missing CSV), invalid_capabilities (bounds reason), invalid_input (field name). The plain from_code discards the detail; callers that log or surface the detail should use this variant. Returns None only when the code is unknown — the detail is always folded in when applicable.

Source

pub fn from_code_with_details(code: &str, details: &[&str]) -> Option<Self>

Like from_code_with_detail, but accepts multi-field details for variants whose Lua return carries more than one detail slot (e.g. ExecutionNotActive ships terminal_outcome, lease_epoch, lifecycle_phase, attempt_id at indexes 2..=5). Indexes below the variant’s expected arity default to "".

Trait Implementations§

Source§

impl Debug for ScriptError

Source§

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

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

impl Display for ScriptError

Source§

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

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

impl Error for ScriptError

1.30.0 · 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<ScriptError> for EngineError

Source§

fn from(err: ScriptError) -> 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, 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> 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.