#[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
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).
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.
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.
Implementations§
Source§impl ScriptError
impl ScriptError
Sourcepub fn class(&self) -> ErrorClass
pub fn class(&self) -> ErrorClass
Classify this error for SDK action dispatch.
Sourcepub fn from_code(code: &str) -> Option<Self>
pub fn from_code(code: &str) -> Option<Self>
Parse an error code string (from Lua return) into a ScriptError.
Sourcepub fn from_code_with_detail(code: &str, detail: &str) -> Option<Self>
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.
Sourcepub fn from_code_with_details(code: &str, details: &[&str]) -> Option<Self>
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
impl Debug for ScriptError
Source§impl Display for ScriptError
impl Display for ScriptError
Source§impl Error for ScriptError
impl Error for ScriptError
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()