pub enum RuntimeError {
Show 38 variants
AuditObligation {
failure: Box<AuditObligationFailure>,
domain_result: Value,
},
Storage(StorageError),
Sqlite(SqliteError),
Query(QueryError),
NotFound(String),
InvalidInput(String),
UnknownVerb(String),
Unconfigured(String),
UnknownModel(String),
Embedding(EmbedError),
Ambiguous(String),
Fusion(FuseError),
UnknownFusionStrategy(String),
Internal(String),
IncompatibleEventStore(String),
GuardedWriteFailed(GuardedWriteFailure),
MissingPackDependency(MissingPackDependency),
MissingPackDependencies(MissingPackDependencies),
CircularPackDependency(CircularPackDependency),
PackRedeclared {
name: String,
first_idx: usize,
second_idx: usize,
},
VerbCollision {
verb: String,
first_pack: String,
second_pack: String,
},
ReservedEnvelopeParam {
pack: String,
verb: String,
param: String,
},
RefusedWithReceipt(Box<ReceiptRefusal>),
RefusedWithEvents {
context: RefusalEventContext,
},
PermissionDenied {
verb: String,
reason: String,
receipt: Box<DenialReceipt>,
},
GateUnavailable {
verb: String,
reason: String,
},
Khive(KhiveError),
NamespaceMismatch {
id: Uuid,
},
AmbiguousPrefix {
prefix: String,
matches: Vec<Uuid>,
},
CrossBackendMergeUnsupported {
into_id: Uuid,
from_id: Uuid,
into_backend: String,
from_backend: String,
},
UnknownRemote {
name: String,
},
RemoteCacheMissing {
remote: String,
namespace: String,
},
AmbiguousId {
id: String,
count: usize,
},
CrossNamespaceWrite {
namespace: String,
},
RemoteFetchError {
remote: String,
message: String,
},
WriteBudgetExceeded {
max_new_entries: u64,
attempted_new_entries: u64,
},
SecretDetected(SecretMatch),
DeadlineExceeded {
operation: String,
budget_ms: u64,
elapsed_ms: u64,
},
}Expand description
Variants cover storage, query, validation, namespace isolation, and permission failures.
Callers should match on InvalidInput for bad arguments, NotFound for missing records,
and NamespaceMismatch (reported as not-found) for cross-namespace access attempts.
Variants§
AuditObligation
The domain handler succeeded, but its post-dispatch obligation did not.
Fields
failure: Box<AuditObligationFailure>Typed reason and source of the obligation failure.
Storage(StorageError)
Sqlite(SqliteError)
Query(QueryError)
NotFound(String)
InvalidInput(String)
UnknownVerb(String)
Unconfigured(String)
UnknownModel(String)
Embedding(EmbedError)
Ambiguous(String)
Fusion(FuseError)
UnknownFusionStrategy(String)
FusionStrategy::Custom { name, .. } named a strategy no pack has
registered via KhiveRuntime::register_fusion_strategy (ADR-012).
Fails closed — never falls back to RRF or any other default.
Internal(String)
IncompatibleEventStore(String)
An EventStore was configured via with_event_store but does not
implement ADR-133’s preflight_event/append_events_idempotent
pair (EventStore::supports_idempotent_audit_batch reports
false). Raised at build() time rather than left to fail every
audited dispatch silently.
GuardedWriteFailed(GuardedWriteFailure)
MissingPackDependency(MissingPackDependency)
MissingPackDependencies(MissingPackDependencies)
CircularPackDependency(CircularPackDependency)
PackRedeclared
VerbCollision
Two packs declared the same Visibility::Verb handler name.
Visibility::Subhandler entries are pack-prefixed and do not
participate in cross-pack collision checks.
ReservedEnvelopeParam
A handler advertised a parameter that request parsing owns at the envelope level.
RefusedWithReceipt(Box<ReceiptRefusal>)
A handler refused the call and wrote a durable receipt naming the refusal.
The durable id rides as its own field. Without it a consumer has to find
the id inside the refusal sentence with a regular expression, which makes
the wording of a message part of the contract and breaks silently the
first time someone rewords it. message keeps whatever text the refusal
already produced, so a reader that does parse it today keeps working.
reason is the refusal’s own explanation, the same value the receipt
stores, so a consumer keeping its own command record does not parse the
sentence for it either. detail carries the surface’s other structured
evidence (for exec, the resolved output cap); it must be a JSON object or
null, and its members are projected beside the fields above without
overriding them.
Boxed so the refusal’s evidence does not widen every Result in the
runtime: the error enum is copied on each ?, the refusal is rare.
RefusedWithEvents
Original typed refusal, with recording evidence independent of the refused write.
Construct through Self::with_refusal_events so no eligible targets means
an unchanged, unadorned refusal.
Fields
context: RefusalEventContextPermissionDenied
Gate denied this verb invocation.
Returned by VerbRegistry::dispatch when the configured Gate returns
GateDecision::Deny. The pack is never invoked. The reason field
carries the deny message produced by the gate implementation.
receipt carries the id of the GateDenied audit row when one
committed, so the caller can cite the refusal, and says whether such
a row exists.
The configured gate could not produce an authorization decision.
This is distinct from Self::PermissionDenied: the pack or
intercepted operation is never invoked, but the gate did not answer
with an explicit denial.
Khive(KhiveError)
A structured khive_types::KhiveError converted into the runtime
layer. The full structured error is preserved so callers can inspect
kind, code, details, and retry_hint without information loss.
NamespaceMismatch
Record exists but belongs to a different namespace than the provided token.
Externally reported as “not found in this namespace” to avoid leaking cross-namespace existence information (timing-oracle mitigation).
AmbiguousPrefix
A short-prefix lookup matched more than one record.
prefix is the 8+ hex-char prefix supplied by the caller.
matches holds the full UUIDs of all matching records (at most 2 are
reported to bound the scan — callers must supply the full UUID to disambiguate).
CrossBackendMergeUnsupported
Cross-backend merge_entity is unsupported in v1.
Both entities must reside on the same backend. To merge entities on different
backends, manually export from_id, delete it, and re-import on into_id’s backend.
UnknownRemote
A kg:// ref names a remote not declared in schema.yaml.
RemoteCacheMissing
A remote cache entry is absent and --fetch was not requested.
AmbiguousId
A short ID matches multiple entities in the same namespace or remote cache.
CrossNamespaceWrite
A write operation targeted a remote namespace, which is read-only.
RemoteFetchError
Remote cache setup or repair failed. Producers redact the source and sanitize diagnostics before constructing this wire-visible error.
WriteBudgetExceeded
A caller-supplied write budget was exceeded during a Compound apply.
max_new_entries is the limit passed by the caller. attempted_new_entries
is consumed + 1, i.e. the create that would have exceeded the cap.
None budget never produces this error (unlimited path).
SecretDetected(SecretMatch)
Write blocked: content matches a secret pattern.
The SecretMatch carries the detector name and a masked excerpt
(first6...Nchars). The full candidate is never stored in the error.
Store a pointer (env-var name, keychain item) rather than the raw value.
DeadlineExceeded
A bounded per-operation deadline elapsed before the operation completed (#889). The operation may still be running in the background (this is a client-observable timeout, not a cancellation signal to the underlying work) — callers should treat this as “no answer within budget”, not “the operation failed or was rolled back”.
Distinct from #836’s narrower ann_ready_timeout_ms, which bounds
only a single cold-miss ANN-build wait inside the recall vector leg
and degrades to an in-band FTS-only result. This variant bounds the
entire operation end-to-end and is surfaced as a typed error so a
caller under sustained contention gets a fast, clear answer instead
of hanging until an upstream client-side ceiling (observed at 300s in
production, #889) fires instead.
Implementations§
Source§impl RuntimeError
impl RuntimeError
Sourcepub fn with_refusal_events(self, recordings: Vec<RefusalEventRecording>) -> Self
pub fn with_refusal_events(self, recordings: Vec<RefusalEventRecording>) -> Self
Attach only evidence for established, eligible targets. Missing/new targets contribute no entry, and an empty batch leaves the error variant unchanged.
Sourcepub fn refusal_source(&self) -> &Self
pub fn refusal_source(&self) -> &Self
Inspect the original typed error without treating event-recording failure as the failed domain operation or losing its policy/retry classification.
Sourcepub fn is_stream_policy_refusal(&self) -> bool
pub fn is_stream_policy_refusal(&self) -> bool
Whether the immutable stream record policy refused this write.
Only the structured runtime marker establishes this class. Ordinary conflicts, caller sequence preconditions, and raw storage failures do not acquire a refusal classification from their rendered messages. These membership guards refuse before applying the requested domain write.
Sourcepub fn permission_denied(
verb: impl Into<String>,
reason: impl Into<String>,
) -> Self
pub fn permission_denied( verb: impl Into<String>, reason: impl Into<String>, ) -> Self
A gate refusal from a path that writes no audit row.
Sourcepub fn channel_ingest_failure_class(&self) -> ChannelIngestFailureClass
pub fn channel_ingest_failure_class(&self) -> ChannelIngestFailureClass
Classify a failed inbound channel write without inspecting rendered error text.
Existing typed safe-retry failures remain retryable. Secret detection is
the first deterministic policy refusal and is permanent. None from
Self::retryable_failure_context is deliberately not interpreted as
permanent: every other variant starts in the bounded Unknown bucket.
Sourcepub fn writer_pool_checkout_timeout_context(
&self,
) -> Option<WriterPoolCheckoutTimeoutContext>
pub fn writer_pool_checkout_timeout_context( &self, ) -> Option<WriterPoolCheckoutTimeoutContext>
Recover a finite-wait pool-checkout timeout without inspecting rendered error text.
Store implementations retain khive_db::SqliteError as the typed
source of StorageError::Driver; this method carries that structure
through the runtime wrapper for the MCP wire serializer. A direct
RuntimeError::Sqlite follows the same classification path.
Sourcepub fn admission_failure_context(&self) -> Option<AdmissionFailureContext>
pub fn admission_failure_context(&self) -> Option<AdmissionFailureContext>
Recover either pre-execution write-admission failure this process can produce, by typed variant rather than rendered message text (#1643). Both are safe to classify as retryable: the request was never accepted, so no partial side effect can exist to roll back.
Sourcepub fn writer_task_failure_context(&self) -> Option<WriterTaskFailureContext>
pub fn writer_task_failure_context(&self) -> Option<WriterTaskFailureContext>
Recover writer-request finality without parsing the rendered storage error. Ordinary proven rollbacks and terminal writer failures are deliberately distinct even when they carry the same request state.
Sourcepub fn retryable_failure_context(&self) -> Option<RetryableFailureContext>
pub fn retryable_failure_context(&self) -> Option<RetryableFailureContext>
Recover every typed failure for which this process can prove that retrying the one failed operation cannot duplicate a side effect.
Trait Implementations§
Source§impl Debug for RuntimeError
impl Debug for RuntimeError
Source§impl Display for RuntimeError
impl Display for RuntimeError
Source§impl Error for RuntimeError
impl Error for RuntimeError
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()
Source§impl From<EmbedError> for RuntimeError
impl From<EmbedError> for RuntimeError
Source§fn from(source: EmbedError) -> Self
fn from(source: EmbedError) -> Self
Source§impl From<EntityTypeError> for RuntimeError
Maps the dependency-light khive-types entity-type resolution error onto
RuntimeError::InvalidInput at the pack boundary: khive-types cannot
depend on khive-runtime, so it cannot produce RuntimeError directly.
impl From<EntityTypeError> for RuntimeError
Maps the dependency-light khive-types entity-type resolution error onto
RuntimeError::InvalidInput at the pack boundary: khive-types cannot
depend on khive-runtime, so it cannot produce RuntimeError directly.
Source§fn from(e: EntityTypeError) -> Self
fn from(e: EntityTypeError) -> Self
Source§impl From<FuseError> for RuntimeError
impl From<FuseError> for RuntimeError
Source§impl From<KhiveError> for RuntimeError
impl From<KhiveError> for RuntimeError
Source§fn from(e: KhiveError) -> Self
fn from(e: KhiveError) -> Self
Source§impl From<QueryError> for RuntimeError
impl From<QueryError> for RuntimeError
Source§fn from(source: QueryError) -> Self
fn from(source: QueryError) -> Self
Source§impl From<SqliteError> for RuntimeError
impl From<SqliteError> for RuntimeError
Source§fn from(error: SqliteError) -> Self
fn from(error: SqliteError) -> Self
Source§impl From<StorageError> for RuntimeError
impl From<StorageError> for RuntimeError
Source§fn from(source: StorageError) -> Self
fn from(source: StorageError) -> Self
Auto Trait Implementations§
impl !RefUnwindSafe for RuntimeError
impl !UnwindSafe for RuntimeError
impl Freeze for RuntimeError
impl Send for RuntimeError
impl Sync for RuntimeError
impl Unpin for RuntimeError
impl UnsafeUnpin for RuntimeError
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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