pub enum RuntimeError {
Show 55 variants
ArtifactNotFound {
name: String,
version: String,
},
ArtifactIntegrityFailed {
name: String,
version: String,
},
LockMissingEntry {
name: String,
},
LockVersionMismatch {
name: String,
requested: String,
pinned: String,
},
ArtifactArchive {
name: String,
version: String,
message: String,
},
ToolComponentCompile {
name: String,
version: String,
message: String,
},
CapsuleCompile(String),
CreateWorkdir {
path: String,
source: Error,
},
WriteToolManifest {
path: String,
source: Error,
},
SystemPromptFileRead {
path: String,
source: Error,
},
CompactionSystemPromptFileRead {
path: String,
source: Error,
},
SystemPromptArtifactRead {
name: String,
source: Error,
},
SkillSourceNotFound {
path: String,
},
SkillSourceMissingSkillMd {
path: String,
},
SkillSourceRead {
path: String,
source: Error,
},
InvalidNetworkAllowEntry {
entry: String,
message: String,
},
InvalidFilesystemScope {
scope: String,
message: String,
},
InvalidReadOnlyPath {
path: String,
message: String,
},
InvalidArtifactConfig {
artifact: String,
message: String,
},
InvalidStateStore {
store: String,
message: String,
},
InvalidConversationRecord {
field: String,
value: String,
message: String,
},
ResumeRecordMissing {
session: String,
context_id: String,
reason: String,
},
ResumeCompactionHookMissing,
StateStoreUnavailable {
store: String,
path: String,
message: String,
},
ContainmentFloorUnmet {
declared: ContainmentClass,
achieved: ContainmentClass,
reason: String,
},
ExportRootOutsideWorkdir {
field: String,
declared: String,
resolved: String,
workdir: String,
},
ReservedToolName {
name: String,
},
EnvAllowStrippedByBackstop {
entries: Vec<StrippedEnvAllowEntry>,
},
RuntimeProvidedToolNotReserved {
name: String,
},
PersistentCapsuleNeedsHandleTtl {
declared_secs: Option<u64>,
ceiling_secs: u64,
},
StagedRuntimeRequiresSealed {
binaries: Vec<String>,
declared: ContainmentClass,
},
ShellBinaryPackageUnreachable {
entries: Vec<UnreachableEntrypoint>,
},
SealedRootConstructionFailed {
detail: String,
},
EgressNamespaceUnavailable {
blocker: EgressNamespaceBlocker,
reason: String,
},
CapsuleExportMissing,
ToolExportMissing {
name: String,
},
CapsuleTrap(String),
CapsuleDeadlineExceeded {
seconds: u64,
},
CapsuleResourceLimit {
message: String,
},
ShellResourceLimitExceeded {
binary: String,
limit: String,
detail: String,
},
ToolDataPathRefused {
tool: String,
path: String,
code: String,
detail: String,
},
CgroupDelegationUnavailable {
reason: String,
},
WorkdirSizeExceeded {
max_bytes: u64,
observed_bytes: u64,
},
WasiInit {
path: String,
message: String,
},
DriverNotConfigured,
DriverNotInstalled(String),
DriverDeclaresNoInferenceAuth {
name: String,
version: String,
reason: Option<String>,
},
InferenceCredentialNotFound {
variable: String,
credentials_file: Option<PathBuf>,
},
SpendLedgerUnavailable {
path: String,
message: String,
},
AgentLoopFailed(String),
PortInUse {
port: u16,
},
SpawnRegistrationFailed {
roost_url: String,
reason: String,
},
SpawnerHandleUnreadable {
reason: String,
},
NativeBinaryPlatformMismatch {
name: String,
binary_platform: String,
host_platform: String,
},
Runtime(String),
}Variants§
ArtifactNotFound
ArtifactIntegrityFailed
LockMissingEntry
LockVersionMismatch
ArtifactArchive
ToolComponentCompile
CapsuleCompile(String)
CreateWorkdir
WriteToolManifest
SystemPromptFileRead
CompactionSystemPromptFileRead
SystemPromptArtifactRead
SkillSourceNotFound
SkillSourceMissingSkillMd
SkillSourceRead
InvalidNetworkAllowEntry
InvalidFilesystemScope
InvalidReadOnlyPath
A capabilities.filesystem.read_only entry is not a usable workdir subpath: it is
absolute, or it escapes the workdir via ... The exact parallel of
Self::InvalidFilesystemScope, raised from
[crate::protected_paths::ProtectedPaths::from_declared] at staging — before any registry
pull, workdir creation or component instantiation — so no call is ever checked against a
rule the runtime could not build.
InvalidArtifactConfig
An artifact entry’s config: block cannot be delivered as MURMUR_ARTIFACT_CONFIG: it is
not a string-keyed mapping, does not serialize to JSON, or exceeds
crate::artifact_config::MAX_ARTIFACT_CONFIG_BYTES. Raised at staging (and from mur run --explain-scope), before any registry pull, workdir creation or component instantiation,
so a malformed channel is refused once at launch rather than one tool call at a time.
InvalidStateStore
A capabilities.state.store name is not a single usable directory segment under
~/.murmur/state/. Raised at staging (and from mur run --explain-scope), before any
registry pull, workdir creation or component instantiation, so a bad name never gets as far
as creating something on disk.
InvalidConversationRecord
A context.record_store value, or a mur run --context value, is not a single usable
directory segment of a conversation record path. Raised at staging, before any registry
pull, workdir creation or component instantiation, so a bad name never gets as far as
creating something on disk.
Distinct from Self::InvalidStateStore because the remedies point at different keys, and
because a record is on by default while a state store is declared: an operator seeing this
may not have written a context: block at all, only a --context flag.
ResumeRecordMissing
mur run --resume named a session whose context kept no conversation record on disk, so
there is nothing to continue. Raised at staging, before this launch’s workdir exists: a
resume that silently started fresh would be indistinguishable from one that worked.
ResumeCompactionHookMissing
mur run --resume-mode compact on a capsule with no hook bound to on-compaction. There
is nothing to produce the summary, and falling back to full would silently give the
operator the mode they did not ask for.
The state store directory a validated name resolves to could not be resolved or created.
Distinct from Self::InvalidStateStore: the declaration is well-formed and the failure is
the host’s — an unset HOME, or a path that cannot be made a 0700 directory.
ContainmentFloorUnmet
The declared containment floor is stronger than what this host’s kernel can back.
Raised in the stage/launch seam, before any registry pull, component compile or workdir
creation — achieved always comes from a live host probe, never from the manifest.
ExportRootOutsideWorkdir
A capsule declares an exports.files.root that, once resolved against the session’s
accessible workdir, lands somewhere else — the root already exists as a symlink pointing
out of it.
Refused at launch rather than per request: an export root outside the workdir is a misconfiguration the operator can fix, and discovering it one served file at a time would mean the first file had already left.
Fields
ReservedToolName
A capsule declares an artifact whose name collides with a tool the runtime provides itself.
The four names in [crate::runtime::RESERVED_TOOL_NAMES] are answered inside
dispatch_agent_tool_unfenced before any allowlist check is reached, and their synthetic
manifests are written after the staging loop. An artifact installed under one of them would
have its manifest overwritten and every call to it answered by the runtime, so the collision
is refused rather than resolved into a tool the capsule can never reach.
EnvAllowStrippedByBackstop
A capsule’s capabilities.env.allow names variables the credential backstop strips from
every guest environment.
The strip in build_wasi_env_allowlist is not negotiable from a manifest, so the entries
can only ever deliver nothing; the declaration is refused rather than left silently inert.
Fields
entries: Vec<StrippedEnvAllowEntry>Every distinct stripped entry, in first-declaration order.
RuntimeProvidedToolNotReserved
A synthetic tool manifest was written under a name absent from
[crate::runtime::RESERVED_TOOL_NAMES].
The inverse of Self::ReservedToolName, and the reason a further runtime-provided tool
cannot be added without reserving its name: an unreserved name is claimable by an artifact,
which would then be installed and silently shadowed at dispatch.
PersistentCapsuleNeedsHandleTtl
A capsule declares exports.peer_files together with lifecycle.after_task: sleep, and
either declared no max_ttl or declared one above the persistent ceiling.
An ephemeral capsule needs no ceiling: teardown destroys the minting key, so every
outstanding handle stops verifying at once and the declared lifetime can never outlive the
process. sleep withdraws that bound deliberately, which makes the declared lifetime the
only one there is — so it has to be declared, and it has to be short.
Fields
StagedRuntimeRequiresSealed
A capsule declares capabilities.shell.staged_runtime without an effective sealed
containment floor.
Deliberately distinct from Self::ContainmentFloorUnmet: that one compares the declared
floor against what the host can back, and its remedy is to lower the floor or move hosts.
This one is decided against the declared floor alone and never looks at the host at all, so
it fires identically on a machine that could deliver sealed — a staged runtime has no
composed root to be staged into unless the capsule asked for one, and quietly launching it
without the mount would leave the interpreter simply absent. Its remedy is to raise the
declared floor (or drop the grant), which is the opposite advice.
binaries names every offending staged_runtime binary so the operator does not have to
re-run to find the second one.
ShellBinaryPackageUnreachable
A sealed capsule allowlists a script whose interpreter’s package tree nothing declared
could make reachable inside the composed root.
Deliberately distinct from Self::StagedRuntimeRequiresSealed, which it sits next to in
stage_session: that one fires when a grant was declared at too low a floor, this one
fires when no grant was declared at all and the floor is already sealed. Their remedies
point in opposite directions — raise the floor there, add a grant here.
entries names every offending allowlist entry so an operator fixing this does not have to
re-run to discover the second script, following the same precedent.
Fields
entries: Vec<UnreachableEntrypoint>SealedRootConstructionFailed
A sealed session’s composed root could not be built in the forked child, after the
pre-launch probe reported the mechanism available.
Deliberately distinct from Self::ContainmentFloorUnmet: that one is a refusal decided
before anything is staged, on a host that never claimed to offer sealed. This one is a
host that claimed it and then failed to deliver — a race, a mount table that changed under
the runtime, or an edge case the cheap probe cannot catch. Conflating the two would tell an
operator to lower their declared floor when the real answer is that something moved.
detail is the message the child wrote to the pre_exec diagnostic pipe, which names the
exact step (unshare, a specific bind mount, pivot_root) and its errno.
This host cannot give a capsule’s native subprocess tree its own network namespace, so the
egress boundary that mediates capabilities.network.allow cannot be built.
Raised before any registry pull, component compile or workdir creation, and raised for
every Linux capsule that can spawn a subprocess — including one whose
capabilities.network.allow is empty. That breadth is the point: with the namespace
missing, an empty allowlist would mean unrestricted egress rather than none, because the
seccomp connect/sendto interception that used to back it was deleted as unsound rather
than kept as a fallback. There is deliberately no path that continues at reduced
enforcement.
Deliberately distinct from Self::ContainmentFloorUnmet, which this would otherwise
look like: that one compares a declared containment class against what the host can
back, and its remedy is to lower the declared floor. A network namespace is not part of
the containment ladder — every class needs it equally — so lowering the floor fixes
nothing here, and offering that advice would be actively misleading.
CapsuleExportMissing
ToolExportMissing
CapsuleTrap(String)
CapsuleDeadlineExceeded
CapsuleResourceLimit
ShellResourceLimitExceeded
ToolDataPathRefused
WorkdirSizeExceeded
WasiInit
DriverNotConfigured
DriverNotInstalled(String)
DriverDeclaresNoInferenceAuth
The configured transport: http driver’s bundled manifest has no usable inference_auth:
block, so the runtime cannot tell how its provider expects the key. Refused at staging,
before any component runs, whether or not inference.api_key is set. reason is None
when the block is absent and says what is wrong when it is malformed.
InferenceCredentialNotFound
inference.api_key: ${variable} names a credential that neither the global config’s
credentials: map nor the launching environment holds. Refused at staging, before the
session directory exists.
spend.machine_tokens_per_day is in effect and the shared ledger it is kept in cannot be
used — an unset HOME, a ~/.murmur/spend that cannot be made a 0700 directory, or a
daily file that cannot be opened. Raised at staging, before the session directory exists
and before any provider request.
AgentLoopFailed(String)
PortInUse
SpawnRegistrationFailed
A session whose manifest declares capabilities.spawn.allow could not register with
mur-roost, so the daemon does not hold the grants it would referee that session’s
delegations against.
Fatal rather than a warning: a capsule that can delegate but is unknown to the daemon is a capsule running outside the only thing that bounds what it may spawn. A capsule that declares no spawn capability never registers and never reaches this.
reason is the transport or daemon-side failure verbatim. Neither this nor anything
derived from it carries a credential or an approval: the registration request’s tokens
travel in headers, and the HTTP client never puts a request header into an error.
SpawnerHandleUnreadable
MURMUR_SPAWNER was set to something that is not a spawner handle.
reason names what about the value could not be read, and nothing derived from it carries
the value itself: a handle names a parent’s address and session, which is not this
process’s to print back out.
NativeBinaryPlatformMismatch
A native tool’s bin/<name> payload was built for another operating system or CPU
architecture than this host.
Raised before any byte of any native binary in the same staging batch reaches the session
workdir: an image this host cannot exec would otherwise be written, made executable, and
then die on a raw Exec format error mid-run, at a point where nothing left says which
artifact was wrong.
Both platforms are current_platform()-shaped strings, or the bare darwin a fat Mach-O
identifies as.
Runtime(String)
Implementations§
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()
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
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