Skip to main content

aube_codes/
errors.rs

1//! Error codes (`ERR_AUBE_*`).
2//!
3//! Each constant's *value* matches its identifier. The `ALL` slice
4//! is the registry — it gates the generated docs page
5//! (`docs/error-codes.md`, produced by the
6//! `generate-error-codes-docs` binary) and the self-tests in
7//! `lib.rs`. New codes go in both places: define a `pub const`,
8//! then add a [`crate::CodeMeta`] entry to `ALL` carrying the
9//! category, one-line description, and (optional) bespoke exit
10//! code.
11
12use crate::CodeMeta;
13
14// ── lockfile ─────────────────────────────────────────────────────────
15pub const ERR_AUBE_NO_LOCKFILE: &str = "ERR_AUBE_NO_LOCKFILE";
16pub const ERR_AUBE_LOCKFILE_PARSE: &str = "ERR_AUBE_LOCKFILE_PARSE";
17pub const ERR_AUBE_LOCKFILE_UNSUPPORTED_FORMAT: &str = "ERR_AUBE_LOCKFILE_UNSUPPORTED_FORMAT";
18pub const ERR_AUBE_RESOLUTION_SHAPE_MISMATCH: &str = "ERR_AUBE_RESOLUTION_SHAPE_MISMATCH";
19
20// ── resolver ─────────────────────────────────────────────────────────
21pub const ERR_AUBE_NO_MATCHING_VERSION: &str = "ERR_AUBE_NO_MATCHING_VERSION";
22pub const ERR_AUBE_NO_MATURE_MATCHING_VERSION: &str = "ERR_AUBE_NO_MATURE_MATCHING_VERSION";
23pub const ERR_AUBE_REGISTRY_ERROR: &str = "ERR_AUBE_REGISTRY_ERROR";
24pub const ERR_AUBE_UNKNOWN_CATALOG: &str = "ERR_AUBE_UNKNOWN_CATALOG";
25pub const ERR_AUBE_UNKNOWN_CATALOG_ENTRY: &str = "ERR_AUBE_UNKNOWN_CATALOG_ENTRY";
26pub const ERR_AUBE_BLOCKED_EXOTIC_SUBDEP: &str = "ERR_AUBE_BLOCKED_EXOTIC_SUBDEP";
27pub const ERR_AUBE_TRUST_DOWNGRADE: &str = "ERR_AUBE_TRUST_DOWNGRADE";
28pub const ERR_AUBE_TRUST_MISSING_TIME: &str = "ERR_AUBE_TRUST_MISSING_TIME";
29// `#[rustfmt::skip]` keeps the long names on a single visual line so the
30// declaration list reads as a flat table — rustfmt would otherwise wrap
31// to a `name: &str =\n    "name";` two-liner for any const past col 100.
32#[rustfmt::skip] pub const ERR_AUBE_TRUST_EXCLUDE_INVALID_VERSION_UNION: &str = "ERR_AUBE_TRUST_EXCLUDE_INVALID_VERSION_UNION";
33#[rustfmt::skip] pub const ERR_AUBE_TRUST_EXCLUDE_NAME_GLOB_WITH_VERSIONS: &str = "ERR_AUBE_TRUST_EXCLUDE_NAME_GLOB_WITH_VERSIONS";
34pub const ERR_AUBE_PEER_CONTEXT_NOT_CONVERGED: &str = "ERR_AUBE_PEER_CONTEXT_NOT_CONVERGED";
35
36// ── registry / network ──────────────────────────────────────────────
37pub const ERR_AUBE_PACKAGE_NOT_FOUND: &str = "ERR_AUBE_PACKAGE_NOT_FOUND";
38pub const ERR_AUBE_ACCESS_ENTITY_NOT_FOUND: &str = "ERR_AUBE_ACCESS_ENTITY_NOT_FOUND";
39pub const ERR_AUBE_VERSION_NOT_FOUND: &str = "ERR_AUBE_VERSION_NOT_FOUND";
40pub const ERR_AUBE_UNAUTHORIZED: &str = "ERR_AUBE_UNAUTHORIZED";
41pub const ERR_AUBE_OFFLINE: &str = "ERR_AUBE_OFFLINE";
42pub const ERR_AUBE_INVALID_PACKAGE_NAME: &str = "ERR_AUBE_INVALID_PACKAGE_NAME";
43pub const ERR_AUBE_REGISTRY_WRITE_REJECTED: &str = "ERR_AUBE_REGISTRY_WRITE_REJECTED";
44pub const ERR_AUBE_MALICIOUS_PACKAGE: &str = "ERR_AUBE_MALICIOUS_PACKAGE";
45pub const ERR_AUBE_LOW_DOWNLOAD_PACKAGE: &str = "ERR_AUBE_LOW_DOWNLOAD_PACKAGE";
46pub const ERR_AUBE_ADVISORY_CHECK_FAILED: &str = "ERR_AUBE_ADVISORY_CHECK_FAILED";
47pub const ERR_AUBE_SECURITY_SCANNER_FATAL: &str = "ERR_AUBE_SECURITY_SCANNER_FATAL";
48pub const ERR_AUBE_SECURITY_SCANNER_FAILED: &str = "ERR_AUBE_SECURITY_SCANNER_FAILED";
49
50// ── tarball / store ─────────────────────────────────────────────────
51pub const ERR_AUBE_TARBALL_INTEGRITY: &str = "ERR_AUBE_TARBALL_INTEGRITY";
52pub const ERR_AUBE_TARBALL_EXTRACT: &str = "ERR_AUBE_TARBALL_EXTRACT";
53pub const ERR_AUBE_PKG_CONTENT_MISMATCH: &str = "ERR_AUBE_PKG_CONTENT_MISMATCH";
54pub const ERR_AUBE_TARBALL_URL_MISMATCH: &str = "ERR_AUBE_TARBALL_URL_MISMATCH";
55pub const ERR_AUBE_NO_HOME: &str = "ERR_AUBE_NO_HOME";
56pub const ERR_AUBE_GIT_ERROR: &str = "ERR_AUBE_GIT_ERROR";
57
58// ── linker ──────────────────────────────────────────────────────────
59pub const ERR_AUBE_LINK_FAILED: &str = "ERR_AUBE_LINK_FAILED";
60pub const ERR_AUBE_PATCH_FAILED: &str = "ERR_AUBE_PATCH_FAILED";
61pub const ERR_AUBE_MISSING_PACKAGE_INDEX: &str = "ERR_AUBE_MISSING_PACKAGE_INDEX";
62pub const ERR_AUBE_UNSAFE_INDEX_KEY: &str = "ERR_AUBE_UNSAFE_INDEX_KEY";
63pub const ERR_AUBE_UNSAFE_PACKAGE_NAME: &str = "ERR_AUBE_UNSAFE_PACKAGE_NAME";
64pub const ERR_AUBE_MISSING_STORE_FILE: &str = "ERR_AUBE_MISSING_STORE_FILE";
65
66// ── scripts ─────────────────────────────────────────────────────────
67pub const ERR_AUBE_SCRIPT_SPAWN: &str = "ERR_AUBE_SCRIPT_SPAWN";
68pub const ERR_AUBE_SCRIPT_NON_ZERO_EXIT: &str = "ERR_AUBE_SCRIPT_NON_ZERO_EXIT";
69#[rustfmt::skip] pub const ERR_AUBE_BUILD_POLICY_UNSUPPORTED_VALUE: &str = "ERR_AUBE_BUILD_POLICY_UNSUPPORTED_VALUE";
70#[rustfmt::skip] pub const ERR_AUBE_BUILD_POLICY_INVALID_VERSION_UNION: &str = "ERR_AUBE_BUILD_POLICY_INVALID_VERSION_UNION";
71#[rustfmt::skip] pub const ERR_AUBE_BUILD_POLICY_WILDCARD_WITH_VERSION: &str = "ERR_AUBE_BUILD_POLICY_WILDCARD_WITH_VERSION";
72
73// ── workspace / filter ──────────────────────────────────────────────
74pub const ERR_AUBE_WORKSPACE_PARSE: &str = "ERR_AUBE_WORKSPACE_PARSE";
75pub const ERR_AUBE_FILTER_EMPTY: &str = "ERR_AUBE_FILTER_EMPTY";
76pub const ERR_AUBE_FILTER_GIT_IO: &str = "ERR_AUBE_FILTER_GIT_IO";
77pub const ERR_AUBE_FILTER_GIT_FAILED: &str = "ERR_AUBE_FILTER_GIT_FAILED";
78
79// ── manifest ────────────────────────────────────────────────────────
80pub const ERR_AUBE_MANIFEST_PARSE: &str = "ERR_AUBE_MANIFEST_PARSE";
81pub const ERR_AUBE_MANIFEST_YAML_PARSE: &str = "ERR_AUBE_MANIFEST_YAML_PARSE";
82
83// ── engine / cli ────────────────────────────────────────────────────
84pub const ERR_AUBE_UNSUPPORTED_ENGINE: &str = "ERR_AUBE_UNSUPPORTED_ENGINE";
85pub const ERR_AUBE_RECURSIVE_NOT_SUPPORTED: &str = "ERR_AUBE_RECURSIVE_NOT_SUPPORTED";
86pub const ERR_AUBE_UNKNOWN_COMMAND: &str = "ERR_AUBE_UNKNOWN_COMMAND";
87pub const ERR_AUBE_NPM_ONLY_COMMAND: &str = "ERR_AUBE_NPM_ONLY_COMMAND";
88pub const ERR_AUBE_COMPLETION_FAILED: &str = "ERR_AUBE_COMPLETION_FAILED";
89pub const ERR_AUBE_REMOVE_PRIOR_INSTALL_DIR: &str = "ERR_AUBE_REMOVE_PRIOR_INSTALL_DIR";
90pub const ERR_AUBE_CONFIG_NESTED_AUBE_KEY: &str = "ERR_AUBE_CONFIG_NESTED_AUBE_KEY";
91pub const ERR_AUBE_CONFLICTING_BUILD_FLAGS: &str = "ERR_AUBE_CONFLICTING_BUILD_FLAGS";
92pub const ERR_AUBE_ACCESS_INVALID_ARGUMENT: &str = "ERR_AUBE_ACCESS_INVALID_ARGUMENT";
93pub const ERR_AUBE_SHIM_CREATE_FAILED: &str = "ERR_AUBE_SHIM_CREATE_FAILED";
94pub const ERR_AUBE_SHIM_EXEC_FAILED: &str = "ERR_AUBE_SHIM_EXEC_FAILED";
95
96// ── node runtime (devEngines.runtime / .node-version / .nvmrc) ──────
97#[rustfmt::skip] pub const ERR_AUBE_RUNTIME_VERSION_UNSATISFIED: &str = "ERR_AUBE_RUNTIME_VERSION_UNSATISFIED";
98#[rustfmt::skip] pub const ERR_AUBE_RUNTIME_NO_MATCHING_VERSION: &str = "ERR_AUBE_RUNTIME_NO_MATCHING_VERSION";
99pub const ERR_AUBE_RUNTIME_DOWNLOAD_FAILED: &str = "ERR_AUBE_RUNTIME_DOWNLOAD_FAILED";
100#[rustfmt::skip] pub const ERR_AUBE_RUNTIME_CHECKSUM_MISMATCH: &str = "ERR_AUBE_RUNTIME_CHECKSUM_MISMATCH";
101pub const ERR_AUBE_RUNTIME_EXTRACT_FAILED: &str = "ERR_AUBE_RUNTIME_EXTRACT_FAILED";
102#[rustfmt::skip] pub const ERR_AUBE_RUNTIME_MISE_INSTALL_FAILED: &str = "ERR_AUBE_RUNTIME_MISE_INSTALL_FAILED";
103#[rustfmt::skip] pub const ERR_AUBE_RUNTIME_UNSUPPORTED_PLATFORM: &str = "ERR_AUBE_RUNTIME_UNSUPPORTED_PLATFORM";
104pub const ERR_AUBE_RUNTIME_IO: &str = "ERR_AUBE_RUNTIME_IO";
105
106// ── misc / safety ──────────────────────────────────────────────────
107pub const ERR_AUBE_INSTALL_CANCELLED: &str = "ERR_AUBE_INSTALL_CANCELLED";
108pub const ERR_AUBE_PATCHES_TRACKING_WRITE: &str = "ERR_AUBE_PATCHES_TRACKING_WRITE";
109pub const ERR_AUBE_UNSAFE_SHEBANG_INTERPRETER: &str = "ERR_AUBE_UNSAFE_SHEBANG_INTERPRETER";
110pub const ERR_AUBE_EMBED_INVALID_PROJECT: &str = "ERR_AUBE_EMBED_INVALID_PROJECT";
111pub const ERR_AUBE_EMBED_INSTALL_FAILED: &str = "ERR_AUBE_EMBED_INSTALL_FAILED";
112pub const ERR_AUBE_FFI_INVALID_ARGUMENT: &str = "ERR_AUBE_FFI_INVALID_ARGUMENT";
113pub const ERR_AUBE_FFI_UNKNOWN_HANDLE: &str = "ERR_AUBE_FFI_UNKNOWN_HANDLE";
114pub const ERR_AUBE_FFI_RUNTIME: &str = "ERR_AUBE_FFI_RUNTIME";
115pub const ERR_AUBE_FFI_PANIC: &str = "ERR_AUBE_FFI_PANIC";
116
117/// Stable category labels that group codes in the generated docs and
118/// in `EXIT_TABLE`'s 10-wide allocation ranges. Public so the docs
119/// generator can iterate them in a deterministic order.
120pub mod category {
121    pub const LOCKFILE: &str = "Lockfile";
122    pub const RESOLVER: &str = "Resolver";
123    pub const TARBALL_STORE: &str = "Tarball / store";
124    pub const REGISTRY_NETWORK: &str = "Registry / network";
125    pub const SCRIPTS: &str = "Scripts / build";
126    pub const LINKER: &str = "Linker";
127    pub const MANIFEST_WORKSPACE: &str = "Manifest / workspace";
128    pub const ENGINE_CLI: &str = "Engine / CLI";
129    pub const MISC_SAFETY: &str = "Misc / safety";
130    /// Add-time / install-time supply-chain policy errors. Paired
131    /// with [`crate::warnings::category::SUPPLY_CHAIN`].
132    pub const SUPPLY_CHAIN: &str = "Supply chain (add-time)";
133}
134
135/// Registry of every error code with its category, description, and
136/// (optional) bespoke exit code. Walked by the
137/// `generate-error-codes-docs` binary and by the self-tests in
138/// `lib.rs` and `exit.rs`. New codes must be added here.
139pub const ALL: &[CodeMeta] = &[
140    // Lockfile
141    CodeMeta {
142        name: ERR_AUBE_NO_LOCKFILE,
143        category: category::LOCKFILE,
144        description: "An operation that required a lockfile (`--frozen-lockfile`, `aube fetch`, etc.) found none in the project.",
145        exit_code: Some(10),
146    },
147    CodeMeta {
148        name: ERR_AUBE_LOCKFILE_PARSE,
149        category: category::LOCKFILE,
150        description: "Lockfile is structurally invalid — version guard failed, YAML shape is wrong, or `yaml_serde` couldn't round-trip the contents.",
151        exit_code: Some(11),
152    },
153    CodeMeta {
154        name: ERR_AUBE_LOCKFILE_UNSUPPORTED_FORMAT,
155        category: category::LOCKFILE,
156        description: "Lockfile filename was recognized but its format isn't supported on this aube version.",
157        exit_code: Some(12),
158    },
159    CodeMeta {
160        name: ERR_AUBE_RESOLUTION_SHAPE_MISMATCH,
161        category: category::LOCKFILE,
162        description: "A registry-style lockfile dependency path is backed by a git, local directory, or direct tarball resolution.",
163        exit_code: Some(13),
164    },
165    // Resolver
166    CodeMeta {
167        name: ERR_AUBE_NO_MATCHING_VERSION,
168        category: category::RESOLVER,
169        description: "No published version of the named package satisfies the requested range.",
170        exit_code: Some(20),
171    },
172    CodeMeta {
173        name: ERR_AUBE_NO_MATURE_MATCHING_VERSION,
174        category: category::RESOLVER,
175        description: "A version satisfying the range exists but every candidate was younger than `minimumReleaseAge` and `minimumReleaseAgeStrict=true`.",
176        exit_code: Some(21),
177    },
178    CodeMeta {
179        name: ERR_AUBE_BLOCKED_EXOTIC_SUBDEP,
180        category: category::RESOLVER,
181        description: "Transitive dep used a `git:` / `file:` / `tarball` specifier and `blockExoticSubdeps=true`.",
182        exit_code: Some(22),
183    },
184    CodeMeta {
185        name: ERR_AUBE_TRUST_DOWNGRADE,
186        category: category::RESOLVER,
187        description: "Picked version dropped trust evidence the prior version had (`trustPolicy=no-downgrade`).",
188        exit_code: Some(23),
189    },
190    CodeMeta {
191        name: ERR_AUBE_TRUST_MISSING_TIME,
192        category: category::RESOLVER,
193        description: "Registry's packument has no `time` entry for the picked version (`trustPolicy=no-downgrade`).",
194        exit_code: Some(24),
195    },
196    CodeMeta {
197        name: ERR_AUBE_UNKNOWN_CATALOG,
198        category: category::RESOLVER,
199        description: "A `catalog:<name>` reference was used but the catalog isn't defined.",
200        exit_code: Some(25),
201    },
202    CodeMeta {
203        name: ERR_AUBE_UNKNOWN_CATALOG_ENTRY,
204        category: category::RESOLVER,
205        description: "The catalog exists but has no entry for the requested package.",
206        exit_code: Some(26),
207    },
208    CodeMeta {
209        name: ERR_AUBE_PEER_CONTEXT_NOT_CONVERGED,
210        category: category::RESOLVER,
211        description: "Peer-context fixed-point loop hit `MAX_ITERATIONS=16` without converging — usually mutually-recursive peers.",
212        exit_code: Some(27),
213    },
214    CodeMeta {
215        name: ERR_AUBE_REGISTRY_ERROR,
216        category: category::RESOLVER,
217        description: "Generic registry error from inside the resolver.",
218        exit_code: None,
219    },
220    CodeMeta {
221        name: ERR_AUBE_TRUST_EXCLUDE_INVALID_VERSION_UNION,
222        category: category::RESOLVER,
223        description: "A `trustPolicyExclude` pattern had an invalid semver range.",
224        exit_code: None,
225    },
226    CodeMeta {
227        name: ERR_AUBE_TRUST_EXCLUDE_NAME_GLOB_WITH_VERSIONS,
228        category: category::RESOLVER,
229        description: "A `trustPolicyExclude` pattern combined a name glob with versions.",
230        exit_code: None,
231    },
232    // Tarball / store
233    CodeMeta {
234        name: ERR_AUBE_TARBALL_INTEGRITY,
235        category: category::TARBALL_STORE,
236        description: "Downloaded tarball's hash didn't match the lockfile's / packument's `dist.integrity`.",
237        exit_code: Some(30),
238    },
239    CodeMeta {
240        name: ERR_AUBE_TARBALL_EXTRACT,
241        category: category::TARBALL_STORE,
242        description: "Tarball couldn't be extracted (corrupt gzip, unexpected entry shape, etc.).",
243        exit_code: Some(31),
244    },
245    CodeMeta {
246        name: ERR_AUBE_PKG_CONTENT_MISMATCH,
247        category: category::TARBALL_STORE,
248        description: "Tarball's `package.json` declared a different `(name, version)` than the resolver expected (`strictStorePkgContentCheck=true`).",
249        exit_code: Some(32),
250    },
251    CodeMeta {
252        name: ERR_AUBE_GIT_ERROR,
253        category: category::TARBALL_STORE,
254        description: "Git operation failed during a `git:` dep prepare or checkout.",
255        exit_code: Some(33),
256    },
257    CodeMeta {
258        name: ERR_AUBE_TARBALL_URL_MISMATCH,
259        category: category::TARBALL_STORE,
260        description: "A registry lockfile entry's explicit tarball URL didn't match the registry metadata for that `(name, version)`.",
261        exit_code: Some(34),
262    },
263    CodeMeta {
264        name: ERR_AUBE_NO_HOME,
265        category: category::TARBALL_STORE,
266        description: "`HOME` (or platform equivalent) is unset, so aube can't locate its store.",
267        exit_code: None,
268    },
269    // Registry / network
270    CodeMeta {
271        name: ERR_AUBE_PACKAGE_NOT_FOUND,
272        category: category::REGISTRY_NETWORK,
273        description: "Registry returned 404 for the package name.",
274        exit_code: Some(40),
275    },
276    CodeMeta {
277        name: ERR_AUBE_ACCESS_ENTITY_NOT_FOUND,
278        category: category::REGISTRY_NETWORK,
279        description: "Registry returned 404 for an access user, organization, or team.",
280        exit_code: None,
281    },
282    CodeMeta {
283        name: ERR_AUBE_VERSION_NOT_FOUND,
284        category: category::REGISTRY_NETWORK,
285        description: "Package exists but the requested version doesn't.",
286        exit_code: Some(41),
287    },
288    CodeMeta {
289        name: ERR_AUBE_UNAUTHORIZED,
290        category: category::REGISTRY_NETWORK,
291        description: "Registry returned 401/403 — missing or invalid auth. Run `aube login`.",
292        exit_code: Some(42),
293    },
294    CodeMeta {
295        name: ERR_AUBE_OFFLINE,
296        category: category::REGISTRY_NETWORK,
297        description: "Offline mode and the requested resource isn't in the local cache.",
298        exit_code: Some(43),
299    },
300    CodeMeta {
301        name: ERR_AUBE_INVALID_PACKAGE_NAME,
302        category: category::REGISTRY_NETWORK,
303        description: "A name doesn't match npm's grammar — rejected before any I/O so a hostile manifest can't use the cache-path builder as a write primitive.",
304        exit_code: Some(44),
305    },
306    CodeMeta {
307        name: ERR_AUBE_REGISTRY_WRITE_REJECTED,
308        category: category::REGISTRY_NETWORK,
309        description: "Registry rejected a publish/deprecate/owner write with a non-2xx response.",
310        exit_code: Some(45),
311    },
312    CodeMeta {
313        name: ERR_AUBE_MALICIOUS_PACKAGE,
314        category: category::REGISTRY_NETWORK,
315        description: "`aube add` refused a package because OSV reports it as malicious (`MAL-*` advisory). Hard block — confirmed-malicious advisories aren't a judgement call.",
316        exit_code: Some(46),
317    },
318    CodeMeta {
319        name: ERR_AUBE_LOW_DOWNLOAD_PACKAGE,
320        category: category::REGISTRY_NETWORK,
321        description: "`aube add` refused a package whose weekly downloads fall below `lowDownloadThreshold` in a non-interactive context (or when stdin is not a TTY). Pass `--allow-low-downloads` to bypass.",
322        exit_code: Some(47),
323    },
324    CodeMeta {
325        name: ERR_AUBE_ADVISORY_CHECK_FAILED,
326        category: category::REGISTRY_NETWORK,
327        description: "`aube add` couldn't reach the OSV advisory API and `advisoryCheck = required` is set. Distinct from `ERR_AUBE_MALICIOUS_PACKAGE` so CI tooling can tell a network outage from a confirmed malicious advisory.",
328        exit_code: Some(49),
329    },
330    CodeMeta {
331        name: ERR_AUBE_SECURITY_SCANNER_FATAL,
332        category: category::SUPPLY_CHAIN,
333        description: "User-configured `securityScanner` returned a `fatal`-level advisory against a package the user is trying to add. Bun-style pluggable scanner contract; the scanner itself decides what counts as fatal.",
334        exit_code: Some(48),
335    },
336    CodeMeta {
337        name: ERR_AUBE_SECURITY_SCANNER_FAILED,
338        category: category::SUPPLY_CHAIN,
339        description: "User-configured `securityScanner` couldn't be spawned, exited non-zero, timed out, or emitted unparseable JSON. Fail-closed by design: a configured scanner that can't run is treated as a refusal, not a free pass. Set `securityScanner = \"\"` to disable the integration when bootstrapping or recovering from a broken scanner.",
340        exit_code: None,
341    },
342    // Scripts / build
343    CodeMeta {
344        name: ERR_AUBE_SCRIPT_NON_ZERO_EXIT,
345        category: category::SCRIPTS,
346        description: "A lifecycle script (`preinstall` / `install` / `postinstall` / a `package.json` script) exited non-zero.",
347        exit_code: Some(50),
348    },
349    CodeMeta {
350        name: ERR_AUBE_SCRIPT_SPAWN,
351        category: category::SCRIPTS,
352        description: "Couldn't spawn a script's interpreter (shell missing, jail setup failed, etc.).",
353        exit_code: Some(51),
354    },
355    CodeMeta {
356        name: ERR_AUBE_BUILD_POLICY_UNSUPPORTED_VALUE,
357        category: category::SCRIPTS,
358        description: "An entry in `allowBuilds` had a value that wasn't `true`/`false`.",
359        exit_code: None,
360    },
361    CodeMeta {
362        name: ERR_AUBE_BUILD_POLICY_INVALID_VERSION_UNION,
363        category: category::SCRIPTS,
364        description: "An `allowBuilds` pattern's version union was unparseable.",
365        exit_code: None,
366    },
367    CodeMeta {
368        name: ERR_AUBE_BUILD_POLICY_WILDCARD_WITH_VERSION,
369        category: category::SCRIPTS,
370        description: "An `allowBuilds` pattern combined a wildcard name with a version union.",
371        exit_code: None,
372    },
373    // Linker
374    CodeMeta {
375        name: ERR_AUBE_PATCH_FAILED,
376        category: category::LINKER,
377        description: "Applying a `pnpm.patchedDependencies` patch failed.",
378        exit_code: Some(60),
379    },
380    CodeMeta {
381        name: ERR_AUBE_LINK_FAILED,
382        category: category::LINKER,
383        description: "Symlink / junction / hardlink couldn't be created — usually permissions or filesystem support.",
384        exit_code: Some(61),
385    },
386    CodeMeta {
387        name: ERR_AUBE_MISSING_PACKAGE_INDEX,
388        category: category::LINKER,
389        description: "Internal: a caller skipped `load_index` but the package wasn't already materialized.",
390        exit_code: Some(62),
391    },
392    CodeMeta {
393        name: ERR_AUBE_MISSING_STORE_FILE,
394        category: category::LINKER,
395        description: "A package index references a CAS shard that doesn't exist on disk. Re-run install to re-fetch.",
396        exit_code: Some(63),
397    },
398    // Manifest / workspace
399    CodeMeta {
400        name: ERR_AUBE_MANIFEST_PARSE,
401        category: category::MANIFEST_WORKSPACE,
402        description: "A `package.json` had a syntax error. miette renders a pointer at the offending byte.",
403        exit_code: Some(70),
404    },
405    CodeMeta {
406        name: ERR_AUBE_WORKSPACE_PARSE,
407        category: category::MANIFEST_WORKSPACE,
408        description: "An `aube-workspace.yaml` / `pnpm-workspace.yaml` was structurally invalid.",
409        exit_code: Some(71),
410    },
411    CodeMeta {
412        name: ERR_AUBE_MANIFEST_YAML_PARSE,
413        category: category::MANIFEST_WORKSPACE,
414        description: "A workspace YAML helper file was structurally invalid (no source pointer available).",
415        exit_code: None,
416    },
417    CodeMeta {
418        name: ERR_AUBE_FILTER_EMPTY,
419        category: category::MANIFEST_WORKSPACE,
420        description: "`--filter` was passed an empty selector.",
421        exit_code: None,
422    },
423    CodeMeta {
424        name: ERR_AUBE_FILTER_GIT_IO,
425        category: category::MANIFEST_WORKSPACE,
426        description: "A `--filter ...[ref]` selector failed to spawn `git`.",
427        exit_code: None,
428    },
429    CodeMeta {
430        name: ERR_AUBE_FILTER_GIT_FAILED,
431        category: category::MANIFEST_WORKSPACE,
432        description: "The git subprocess for a `--filter ...[ref]` selector exited non-zero.",
433        exit_code: None,
434    },
435    // Engine / CLI
436    CodeMeta {
437        name: ERR_AUBE_UNSUPPORTED_ENGINE,
438        category: category::ENGINE_CLI,
439        description: "One or more packages declared an `engines` constraint incompatible with the running Node/aube and `engine-strict=true`.",
440        exit_code: Some(80),
441    },
442    CodeMeta {
443        name: ERR_AUBE_UNKNOWN_COMMAND,
444        category: category::ENGINE_CLI,
445        description: "The named subcommand isn't a built-in aube command and isn't a script in the manifest.",
446        exit_code: Some(81),
447    },
448    CodeMeta {
449        name: ERR_AUBE_NPM_ONLY_COMMAND,
450        category: category::ENGINE_CLI,
451        description: "The user invoked an npm-only command (`whoami`, `token`, `owner`, `search`, `pkg`, `set-script`) — aube doesn't implement these; use npm.",
452        exit_code: Some(82),
453    },
454    CodeMeta {
455        name: ERR_AUBE_RECURSIVE_NOT_SUPPORTED,
456        category: category::ENGINE_CLI,
457        description: "A command was invoked under `--recursive` but doesn't support recursive execution.",
458        exit_code: None,
459    },
460    CodeMeta {
461        name: ERR_AUBE_COMPLETION_FAILED,
462        category: category::ENGINE_CLI,
463        description: "`aube completion` couldn't invoke `usage` to render the shell completions.",
464        exit_code: None,
465    },
466    CodeMeta {
467        name: ERR_AUBE_REMOVE_PRIOR_INSTALL_DIR,
468        category: category::ENGINE_CLI,
469        description: "Couldn't clean up a prior global install dir before re-installing.",
470        exit_code: None,
471    },
472    CodeMeta {
473        name: ERR_AUBE_CONFIG_NESTED_AUBE_KEY,
474        category: category::ENGINE_CLI,
475        description: "`aube config set <prefix>.<sub> …` was used for a key whose prefix is an aube map setting (e.g. `allowBuilds.<pkg>`). Such nested writes would otherwise land in `.npmrc` where aube doesn't read them and npm warns/errors about the unknown key — set the map in workspace yaml or `package.json#aube.<prefix>` instead.",
476        exit_code: None,
477    },
478    CodeMeta {
479        name: ERR_AUBE_CONFLICTING_BUILD_FLAGS,
480        category: category::ENGINE_CLI,
481        description: "`aube add` was passed the same package name in both `--allow-build` and `--deny-build`.",
482        exit_code: None,
483    },
484    CodeMeta {
485        name: ERR_AUBE_ACCESS_INVALID_ARGUMENT,
486        category: category::ENGINE_CLI,
487        description: "`aube access` received an invalid access setting, permission level, team, or package argument.",
488        exit_code: None,
489    },
490    CodeMeta {
491        name: ERR_AUBE_SHIM_CREATE_FAILED,
492        category: category::ENGINE_CLI,
493        description: "`aube activate <shell>` couldn't create or refresh an executable shim in aube's shim directory.",
494        exit_code: None,
495    },
496    CodeMeta {
497        name: ERR_AUBE_SHIM_EXEC_FAILED,
498        category: category::ENGINE_CLI,
499        description: "A runtime tool shim resolved its target but couldn't exec or spawn the selected tool.",
500        exit_code: None,
501    },
502    // Node runtime (devEngines.runtime / .node-version / .nvmrc)
503    CodeMeta {
504        name: ERR_AUBE_RUNTIME_VERSION_UNSATISFIED,
505        category: category::ENGINE_CLI,
506        description: "The project requires a Node.js version that isn't available and policy forbids fetching it (`devEngines.runtime` with `onFail: \"error\"`, `runtimeOnFail=error`, or offline mode with nothing installed).",
507        exit_code: Some(83),
508    },
509    CodeMeta {
510        name: ERR_AUBE_RUNTIME_NO_MATCHING_VERSION,
511        category: category::ENGINE_CLI,
512        description: "No Node.js release in the dist index satisfies the requested version (bad range, unknown LTS codename, or no build for this platform).",
513        exit_code: Some(84),
514    },
515    CodeMeta {
516        name: ERR_AUBE_RUNTIME_DOWNLOAD_FAILED,
517        category: category::ENGINE_CLI,
518        description: "Fetching the Node.js dist index, checksum file, or release archive failed after retries.",
519        exit_code: Some(85),
520    },
521    CodeMeta {
522        name: ERR_AUBE_RUNTIME_CHECKSUM_MISMATCH,
523        category: category::ENGINE_CLI,
524        description: "A downloaded Node.js archive's SHA-256 didn't match the lockfile pin or `SHASUMS256.txt`. The archive is discarded and never retried automatically.",
525        exit_code: Some(86),
526    },
527    CodeMeta {
528        name: ERR_AUBE_RUNTIME_EXTRACT_FAILED,
529        category: category::ENGINE_CLI,
530        description: "A Node.js release archive was corrupt or contained unsafe entry paths.",
531        exit_code: Some(87),
532    },
533    CodeMeta {
534        name: ERR_AUBE_RUNTIME_MISE_INSTALL_FAILED,
535        category: category::ENGINE_CLI,
536        description: "Delegating a Node.js install to mise failed — `mise install node@<version>` exited non-zero or the install wasn't discoverable afterwards. Fatal only under `runtimeInstaller=mise`; `auto` falls back to aube's own download.",
537        exit_code: Some(88),
538    },
539    CodeMeta {
540        name: ERR_AUBE_RUNTIME_UNSUPPORTED_PLATFORM,
541        category: category::ENGINE_CLI,
542        description: "No official Node.js build exists for this OS/architecture/libc. Set `nodeDownloadMirrors` to a mirror that carries one, or install Node via mise/system.",
543        exit_code: Some(89),
544    },
545    CodeMeta {
546        name: ERR_AUBE_RUNTIME_IO,
547        category: category::ENGINE_CLI,
548        description: "A filesystem operation in the runtime store failed (lock acquisition, staging, or publishing an install). Not a download failure — the message names the failing path.",
549        exit_code: None,
550    },
551    // Misc / safety
552    CodeMeta {
553        name: ERR_AUBE_INSTALL_CANCELLED,
554        category: category::MISC_SAFETY,
555        description: "An in-process install was cooperatively cancelled by its embedding host. Cancellation is observed at safe install boundaries so an in-flight filesystem phase is not abandoned mid-mutation.",
556        exit_code: None,
557    },
558    CodeMeta {
559        name: ERR_AUBE_UNSAFE_INDEX_KEY,
560        category: category::MISC_SAFETY,
561        description: "A package index key tried to escape its directory (path traversal defense in depth).",
562        exit_code: Some(90),
563    },
564    CodeMeta {
565        name: ERR_AUBE_UNSAFE_SHEBANG_INTERPRETER,
566        category: category::MISC_SAFETY,
567        description: "A `#!` shebang named an unsafe interpreter when generating a shim — substituted with `node` instead. Surfaced as `tracing::error!` but install continues.",
568        exit_code: Some(91),
569    },
570    CodeMeta {
571        name: ERR_AUBE_EMBED_INVALID_PROJECT,
572        category: category::MISC_SAFETY,
573        description: "An in-process embedder was given a project directory that could not be created, inspected, or resolved.",
574        exit_code: None,
575    },
576    CodeMeta {
577        name: ERR_AUBE_EMBED_INSTALL_FAILED,
578        category: category::MISC_SAFETY,
579        description: "An in-process embedder could not initialize its host callback or received an install failure without a more specific stable code.",
580        exit_code: None,
581    },
582    CodeMeta {
583        name: ERR_AUBE_FFI_INVALID_ARGUMENT,
584        category: category::MISC_SAFETY,
585        description: "A C ABI call received a null pointer, invalid UTF-8, malformed JSON, or an unsupported option value.",
586        exit_code: None,
587    },
588    CodeMeta {
589        name: ERR_AUBE_FFI_UNKNOWN_HANDLE,
590        category: category::MISC_SAFETY,
591        description: "A C ABI wait or cancellation call referenced an unknown or already-consumed operation handle.",
592        exit_code: None,
593    },
594    CodeMeta {
595        name: ERR_AUBE_FFI_RUNTIME,
596        category: category::MISC_SAFETY,
597        description: "The C ABI could not initialize or use its internal asynchronous runtime.",
598        exit_code: None,
599    },
600    CodeMeta {
601        name: ERR_AUBE_FFI_PANIC,
602        category: category::MISC_SAFETY,
603        description: "A panic was caught at the C ABI boundary before it could cross into the host process.",
604        exit_code: None,
605    },
606    CodeMeta {
607        name: ERR_AUBE_UNSAFE_PACKAGE_NAME,
608        category: category::MISC_SAFETY,
609        description: "A package/dependency alias would escape its `node_modules` slot if linked.",
610        exit_code: Some(92),
611    },
612    CodeMeta {
613        name: ERR_AUBE_PATCHES_TRACKING_WRITE,
614        category: category::MISC_SAFETY,
615        description: "Couldn't write `.aube-applied-patches.json` after applying patches. Non-fatal; next install may miss stale patched entries.",
616        exit_code: None,
617    },
618];