capsule_runtime/
errors.rs1use std::path::PathBuf;
2
3use thiserror::Error;
4
5#[derive(Debug, Error)]
6pub enum RuntimeError {
7 #[error("artifact {name}@{version} not found in registry")]
8 ArtifactNotFound { name: String, version: String },
9
10 #[error("artifact integrity check failed for {name}@{version}")]
11 ArtifactIntegrityFailed { name: String, version: String },
12
13 #[error("lockfile missing artifact entry for '{name}'")]
14 LockMissingEntry { name: String },
15
16 #[error(
17 "lockfile version mismatch for '{name}': manifest requested {requested}, lock pinned {pinned}"
18 )]
19 LockVersionMismatch {
20 name: String,
21 requested: String,
22 pinned: String,
23 },
24
25 #[error("failed to read artifact archive for {name}@{version}: {message}")]
26 ArtifactArchive {
27 name: String,
28 version: String,
29 message: String,
30 },
31
32 #[error("failed to compile component for {name}@{version}: {message}")]
33 ToolComponentCompile {
34 name: String,
35 version: String,
36 message: String,
37 },
38
39 #[error("failed to compile capsule component: {0}")]
40 CapsuleCompile(String),
41
42 #[error("failed to create workdir at {path}: {source}")]
43 CreateWorkdir {
44 path: String,
45 #[source]
46 source: std::io::Error,
47 },
48
49 #[error("failed to write tool manifest at {path}: {source}")]
50 WriteToolManifest {
51 path: String,
52 #[source]
53 source: std::io::Error,
54 },
55
56 #[error("failed to read inference.system_prompt_file at {path}: {source}")]
57 SystemPromptFileRead {
58 path: String,
59 #[source]
60 source: std::io::Error,
61 },
62
63 #[error(
64 "inference.system_prompt_artifact '{name}': skill.md not found or unreadable; \
65 ensure the skill is declared in artifacts: and the capsule was staged"
66 )]
67 SystemPromptArtifactRead {
68 name: String,
69 #[source]
70 source: std::io::Error,
71 },
72
73 #[error("skill source path not found: {path}")]
74 SkillSourceNotFound { path: String },
75
76 #[error("skill source directory '{path}' contains no skill.md")]
77 SkillSourceMissingSkillMd { path: String },
78
79 #[error("failed to read skill source at {path}: {source}")]
80 SkillSourceRead {
81 path: String,
82 #[source]
83 source: std::io::Error,
84 },
85
86 #[error("invalid network capability allow entry '{entry}': {message}")]
87 InvalidNetworkAllowEntry { entry: String, message: String },
88
89 #[error("invalid filesystem capability scope '{scope}': {message}")]
90 InvalidFilesystemScope { scope: String, message: String },
91
92 #[error(
93 "capsule component missing export murmur:capsule/run@0.1.0#run; rebuild the artifact against the versioned WIT (run `mur install` for a default artifact, or rebuild from source otherwise)"
94 )]
95 CapsuleExportMissing,
96
97 #[error(
98 "tool component '{name}' missing export murmur:tool/run@0.1.0#run; rebuild the artifact against the versioned WIT (run `mur install` for a default artifact, or rebuild from source otherwise)"
99 )]
100 ToolExportMissing { name: String },
101
102 #[error("capsule execution trapped: {0}")]
103 CapsuleTrap(String),
104
105 #[error(
106 "capsule execution exceeded its {seconds}s deadline and was interrupted; \
107 raise capabilities.limits.deadline_seconds in murmur.yaml if the capsule \
108 legitimately needs longer"
109 )]
110 CapsuleDeadlineExceeded { seconds: u64 },
111
112 #[error("capsule execution exceeded its configured resource limits: {message}")]
113 CapsuleResourceLimit { message: String },
114
115 #[error("failed to initialize WASI for {path}: {message}")]
116 WasiInit { path: String, message: String },
117
118 #[error("inference driver is not configured; add inference.driver.artifact to murmur.yaml")]
119 DriverNotConfigured,
120
121 #[error("inference driver '{0}' is not installed in the local tool registry")]
122 DriverNotInstalled(String),
123
124 #[error("agent loop failed: {0}")]
125 AgentLoopFailed(String),
126
127 #[error("internal_port {port} is already bound; choose another port or omit internal_port to use an OS-assigned port")]
128 PortInUse { port: u16 },
129
130 #[error("runtime failure: {0}")]
131 Runtime(String),
132}
133
134impl RuntimeError {
135 #[must_use]
136 pub fn artifact_not_found(name: impl Into<String>, version: impl Into<String>) -> Self {
137 Self::ArtifactNotFound {
138 name: name.into(),
139 version: version.into(),
140 }
141 }
142
143 #[must_use]
144 pub fn artifact_integrity_failed(name: impl Into<String>, version: impl Into<String>) -> Self {
145 Self::ArtifactIntegrityFailed {
146 name: name.into(),
147 version: version.into(),
148 }
149 }
150
151 #[must_use]
152 pub fn wasi(path: PathBuf, message: impl Into<String>) -> Self {
153 Self::WasiInit {
154 path: path.display().to_string(),
155 message: message.into(),
156 }
157 }
158}