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";
19pub const ERR_AUBE_LOCKFILE_CONFIG_MISMATCH: &str = "ERR_AUBE_LOCKFILE_CONFIG_MISMATCH";
20pub const ERR_AUBE_UNSUPPORTED_NAMED_REGISTRY: &str = "ERR_AUBE_UNSUPPORTED_NAMED_REGISTRY";
21
22// ── resolver ─────────────────────────────────────────────────────────
23pub const ERR_AUBE_NO_MATCHING_VERSION: &str = "ERR_AUBE_NO_MATCHING_VERSION";
24pub const ERR_AUBE_NO_MATURE_MATCHING_VERSION: &str = "ERR_AUBE_NO_MATURE_MATCHING_VERSION";
25pub const ERR_AUBE_REGISTRY_ERROR: &str = "ERR_AUBE_REGISTRY_ERROR";
26pub const ERR_AUBE_UNKNOWN_CATALOG: &str = "ERR_AUBE_UNKNOWN_CATALOG";
27pub const ERR_AUBE_UNKNOWN_CATALOG_ENTRY: &str = "ERR_AUBE_UNKNOWN_CATALOG_ENTRY";
28pub const ERR_AUBE_BLOCKED_EXOTIC_SUBDEP: &str = "ERR_AUBE_BLOCKED_EXOTIC_SUBDEP";
29pub const ERR_AUBE_TRUST_DOWNGRADE: &str = "ERR_AUBE_TRUST_DOWNGRADE";
30pub const ERR_AUBE_TRUST_MISSING_TIME: &str = "ERR_AUBE_TRUST_MISSING_TIME";
31// `#[rustfmt::skip]` keeps the long names on a single visual line so the
32// declaration list reads as a flat table — rustfmt would otherwise wrap
33// to a `name: &str =\n    "name";` two-liner for any const past col 100.
34#[rustfmt::skip] pub const ERR_AUBE_TRUST_EXCLUDE_INVALID_VERSION_UNION: &str = "ERR_AUBE_TRUST_EXCLUDE_INVALID_VERSION_UNION";
35#[rustfmt::skip] pub const ERR_AUBE_TRUST_EXCLUDE_NAME_GLOB_WITH_VERSIONS: &str = "ERR_AUBE_TRUST_EXCLUDE_NAME_GLOB_WITH_VERSIONS";
36pub const ERR_AUBE_PEER_CONTEXT_NOT_CONVERGED: &str = "ERR_AUBE_PEER_CONTEXT_NOT_CONVERGED";
37
38// ── registry / network ──────────────────────────────────────────────
39pub const ERR_AUBE_PACKAGE_NOT_FOUND: &str = "ERR_AUBE_PACKAGE_NOT_FOUND";
40pub const ERR_AUBE_ACCESS_ENTITY_NOT_FOUND: &str = "ERR_AUBE_ACCESS_ENTITY_NOT_FOUND";
41pub const ERR_AUBE_VERSION_NOT_FOUND: &str = "ERR_AUBE_VERSION_NOT_FOUND";
42pub const ERR_AUBE_UNAUTHORIZED: &str = "ERR_AUBE_UNAUTHORIZED";
43pub const ERR_AUBE_OFFLINE: &str = "ERR_AUBE_OFFLINE";
44pub const ERR_AUBE_INVALID_PACKAGE_NAME: &str = "ERR_AUBE_INVALID_PACKAGE_NAME";
45pub const ERR_AUBE_REGISTRY_WRITE_REJECTED: &str = "ERR_AUBE_REGISTRY_WRITE_REJECTED";
46pub const ERR_AUBE_MALICIOUS_PACKAGE: &str = "ERR_AUBE_MALICIOUS_PACKAGE";
47pub const ERR_AUBE_SIMILAR_PACKAGE_NAME: &str = "ERR_AUBE_SIMILAR_PACKAGE_NAME";
48pub const ERR_AUBE_LOW_DOWNLOAD_PACKAGE: &str = "ERR_AUBE_LOW_DOWNLOAD_PACKAGE";
49pub const ERR_AUBE_NEW_PACKAGE_NAME: &str = "ERR_AUBE_NEW_PACKAGE_NAME";
50pub const ERR_AUBE_PACKAGE_AGE_CHECK_FAILED: &str = "ERR_AUBE_PACKAGE_AGE_CHECK_FAILED";
51pub const ERR_AUBE_ADVISORY_CHECK_FAILED: &str = "ERR_AUBE_ADVISORY_CHECK_FAILED";
52pub const ERR_AUBE_SECURITY_SCANNER_FATAL: &str = "ERR_AUBE_SECURITY_SCANNER_FATAL";
53pub const ERR_AUBE_SECURITY_SCANNER_FAILED: &str = "ERR_AUBE_SECURITY_SCANNER_FAILED";
54pub const ERR_AUBE_WEB_LOGIN_RESPONSE_TOO_LARGE: &str = "ERR_AUBE_WEB_LOGIN_RESPONSE_TOO_LARGE";
55
56// ── tarball / store ─────────────────────────────────────────────────
57pub const ERR_AUBE_TARBALL_INTEGRITY: &str = "ERR_AUBE_TARBALL_INTEGRITY";
58pub const ERR_AUBE_TARBALL_EXTRACT: &str = "ERR_AUBE_TARBALL_EXTRACT";
59pub const ERR_AUBE_PKG_CONTENT_MISMATCH: &str = "ERR_AUBE_PKG_CONTENT_MISMATCH";
60pub const ERR_AUBE_TARBALL_URL_MISMATCH: &str = "ERR_AUBE_TARBALL_URL_MISMATCH";
61pub const ERR_AUBE_NO_HOME: &str = "ERR_AUBE_NO_HOME";
62pub const ERR_AUBE_GIT_ERROR: &str = "ERR_AUBE_GIT_ERROR";
63pub const ERR_AUBE_STORE_INDEX_SCAN_FAILED: &str = "ERR_AUBE_STORE_INDEX_SCAN_FAILED";
64pub const ERR_AUBE_GVS_PRUNE_FAILED: &str = "ERR_AUBE_GVS_PRUNE_FAILED";
65pub const ERR_AUBE_STORE_PRUNE_LOCK_FAILED: &str = "ERR_AUBE_STORE_PRUNE_LOCK_FAILED";
66pub const ERR_AUBE_STORE_PRUNE_FAILED: &str = "ERR_AUBE_STORE_PRUNE_FAILED";
67
68// ── linker ──────────────────────────────────────────────────────────
69pub const ERR_AUBE_LINK_FAILED: &str = "ERR_AUBE_LINK_FAILED";
70pub const ERR_AUBE_PATCH_FAILED: &str = "ERR_AUBE_PATCH_FAILED";
71pub const ERR_AUBE_MISSING_PACKAGE_INDEX: &str = "ERR_AUBE_MISSING_PACKAGE_INDEX";
72pub const ERR_AUBE_UNSAFE_INDEX_KEY: &str = "ERR_AUBE_UNSAFE_INDEX_KEY";
73pub const ERR_AUBE_UNSAFE_PACKAGE_NAME: &str = "ERR_AUBE_UNSAFE_PACKAGE_NAME";
74pub const ERR_AUBE_MISSING_STORE_FILE: &str = "ERR_AUBE_MISSING_STORE_FILE";
75pub const ERR_AUBE_UNSAFE_MODULES_DIR: &str = "ERR_AUBE_UNSAFE_MODULES_DIR";
76
77// ── scripts ─────────────────────────────────────────────────────────
78pub const ERR_AUBE_SCRIPT_SPAWN: &str = "ERR_AUBE_SCRIPT_SPAWN";
79pub const ERR_AUBE_SCRIPT_NON_ZERO_EXIT: &str = "ERR_AUBE_SCRIPT_NON_ZERO_EXIT";
80#[rustfmt::skip] pub const ERR_AUBE_BUILD_POLICY_UNSUPPORTED_VALUE: &str = "ERR_AUBE_BUILD_POLICY_UNSUPPORTED_VALUE";
81#[rustfmt::skip] pub const ERR_AUBE_BUILD_POLICY_INVALID_VERSION_UNION: &str = "ERR_AUBE_BUILD_POLICY_INVALID_VERSION_UNION";
82#[rustfmt::skip] pub const ERR_AUBE_BUILD_POLICY_WILDCARD_WITH_VERSION: &str = "ERR_AUBE_BUILD_POLICY_WILDCARD_WITH_VERSION";
83
84// ── workspace / filter ──────────────────────────────────────────────
85pub const ERR_AUBE_WORKSPACE_PARSE: &str = "ERR_AUBE_WORKSPACE_PARSE";
86pub const ERR_AUBE_FILTER_EMPTY: &str = "ERR_AUBE_FILTER_EMPTY";
87pub const ERR_AUBE_FILTER_GIT_IO: &str = "ERR_AUBE_FILTER_GIT_IO";
88pub const ERR_AUBE_FILTER_GIT_FAILED: &str = "ERR_AUBE_FILTER_GIT_FAILED";
89
90// ── manifest ────────────────────────────────────────────────────────
91pub const ERR_AUBE_MANIFEST_PARSE: &str = "ERR_AUBE_MANIFEST_PARSE";
92pub const ERR_AUBE_MANIFEST_YAML_PARSE: &str = "ERR_AUBE_MANIFEST_YAML_PARSE";
93pub const ERR_AUBE_INVALID_PACKAGE_EXTENSION: &str = "ERR_AUBE_INVALID_PACKAGE_EXTENSION";
94
95// ── engine / cli ────────────────────────────────────────────────────
96pub const ERR_AUBE_UNSUPPORTED_ENGINE: &str = "ERR_AUBE_UNSUPPORTED_ENGINE";
97pub const ERR_AUBE_RECURSIVE_NOT_SUPPORTED: &str = "ERR_AUBE_RECURSIVE_NOT_SUPPORTED";
98pub const ERR_AUBE_UNKNOWN_COMMAND: &str = "ERR_AUBE_UNKNOWN_COMMAND";
99pub const ERR_AUBE_NPM_ONLY_COMMAND: &str = "ERR_AUBE_NPM_ONLY_COMMAND";
100pub const ERR_AUBE_COMPLETION_FAILED: &str = "ERR_AUBE_COMPLETION_FAILED";
101pub const ERR_AUBE_USAGE_SPEC_WRITE_FAILED: &str = "ERR_AUBE_USAGE_SPEC_WRITE_FAILED";
102pub const ERR_AUBE_REMOVE_PRIOR_INSTALL_DIR: &str = "ERR_AUBE_REMOVE_PRIOR_INSTALL_DIR";
103pub const ERR_AUBE_CONFIG_NESTED_AUBE_KEY: &str = "ERR_AUBE_CONFIG_NESTED_AUBE_KEY";
104pub const ERR_AUBE_CONFLICTING_BUILD_FLAGS: &str = "ERR_AUBE_CONFLICTING_BUILD_FLAGS";
105pub const ERR_AUBE_ACCESS_INVALID_ARGUMENT: &str = "ERR_AUBE_ACCESS_INVALID_ARGUMENT";
106pub const ERR_AUBE_PUBLISH_SOURCE_NOT_FOUND: &str = "ERR_AUBE_PUBLISH_SOURCE_NOT_FOUND";
107pub const ERR_AUBE_SHIM_CREATE_FAILED: &str = "ERR_AUBE_SHIM_CREATE_FAILED";
108pub const ERR_AUBE_SHIM_EXEC_FAILED: &str = "ERR_AUBE_SHIM_EXEC_FAILED";
109
110// ── node runtime (devEngines.runtime / .node-version / .nvmrc) ──────
111#[rustfmt::skip] pub const ERR_AUBE_RUNTIME_VERSION_UNSATISFIED: &str = "ERR_AUBE_RUNTIME_VERSION_UNSATISFIED";
112#[rustfmt::skip] pub const ERR_AUBE_RUNTIME_NO_MATCHING_VERSION: &str = "ERR_AUBE_RUNTIME_NO_MATCHING_VERSION";
113pub const ERR_AUBE_RUNTIME_DOWNLOAD_FAILED: &str = "ERR_AUBE_RUNTIME_DOWNLOAD_FAILED";
114#[rustfmt::skip] pub const ERR_AUBE_RUNTIME_CHECKSUM_MISMATCH: &str = "ERR_AUBE_RUNTIME_CHECKSUM_MISMATCH";
115pub const ERR_AUBE_RUNTIME_EXTRACT_FAILED: &str = "ERR_AUBE_RUNTIME_EXTRACT_FAILED";
116#[rustfmt::skip] pub const ERR_AUBE_RUNTIME_MISE_INSTALL_FAILED: &str = "ERR_AUBE_RUNTIME_MISE_INSTALL_FAILED";
117#[rustfmt::skip] pub const ERR_AUBE_RUNTIME_UNSUPPORTED_PLATFORM: &str = "ERR_AUBE_RUNTIME_UNSUPPORTED_PLATFORM";
118pub const ERR_AUBE_RUNTIME_IO: &str = "ERR_AUBE_RUNTIME_IO";
119#[rustfmt::skip] pub const ERR_AUBE_SELF_UPDATE_UNSUPPORTED_PLATFORM: &str = "ERR_AUBE_SELF_UPDATE_UNSUPPORTED_PLATFORM";
120
121// ── misc / safety ──────────────────────────────────────────────────
122pub const ERR_AUBE_INSTALL_CANCELLED: &str = "ERR_AUBE_INSTALL_CANCELLED";
123pub const ERR_AUBE_PATCHES_TRACKING_WRITE: &str = "ERR_AUBE_PATCHES_TRACKING_WRITE";
124pub const ERR_AUBE_UNSAFE_SHEBANG_INTERPRETER: &str = "ERR_AUBE_UNSAFE_SHEBANG_INTERPRETER";
125pub const ERR_AUBE_EMBED_INVALID_PROJECT: &str = "ERR_AUBE_EMBED_INVALID_PROJECT";
126pub const ERR_AUBE_EMBED_INSTALL_FAILED: &str = "ERR_AUBE_EMBED_INSTALL_FAILED";
127pub const ERR_AUBE_EMBED_INVALID_SETTING: &str = "ERR_AUBE_EMBED_INVALID_SETTING";
128pub const ERR_AUBE_EMBED_ALREADY_INITIALIZED: &str = "ERR_AUBE_EMBED_ALREADY_INITIALIZED";
129pub const ERR_AUBE_FFI_INVALID_ARGUMENT: &str = "ERR_AUBE_FFI_INVALID_ARGUMENT";
130pub const ERR_AUBE_FFI_UNKNOWN_HANDLE: &str = "ERR_AUBE_FFI_UNKNOWN_HANDLE";
131pub const ERR_AUBE_FFI_RUNTIME: &str = "ERR_AUBE_FFI_RUNTIME";
132pub const ERR_AUBE_FFI_PANIC: &str = "ERR_AUBE_FFI_PANIC";
133
134/// Stable category labels that group codes in the generated docs and
135/// in `EXIT_TABLE`'s 10-wide allocation ranges. Public so the docs
136/// generator can iterate them in a deterministic order.
137pub mod category {
138    pub const LOCKFILE: &str = "Lockfile";
139    pub const RESOLVER: &str = "Resolver";
140    pub const TARBALL_STORE: &str = "Tarball / store";
141    pub const REGISTRY_NETWORK: &str = "Registry / network";
142    pub const SCRIPTS: &str = "Scripts / build";
143    pub const LINKER: &str = "Linker";
144    pub const MANIFEST_WORKSPACE: &str = "Manifest / workspace";
145    pub const ENGINE_CLI: &str = "Engine / CLI";
146    pub const MISC_SAFETY: &str = "Misc / safety";
147    /// Add-time / install-time supply-chain policy errors. Paired
148    /// with [`crate::warnings::category::SUPPLY_CHAIN`].
149    pub const SUPPLY_CHAIN: &str = "Supply chain (add-time)";
150}
151
152/// Registry of every error code with its category, description, and
153/// (optional) bespoke exit code. Walked by the
154/// `generate-error-codes-docs` binary and by the self-tests in
155/// `lib.rs` and `exit.rs`. New codes must be added here.
156pub const ALL: &[CodeMeta] = &[
157    // Lockfile
158    CodeMeta {
159        name: ERR_AUBE_NO_LOCKFILE,
160        category: category::LOCKFILE,
161        description: "An operation that required a lockfile (`--frozen-lockfile`, `aube fetch`, etc.) found none in the project.",
162        exit_code: Some(10),
163    },
164    CodeMeta {
165        name: ERR_AUBE_LOCKFILE_PARSE,
166        category: category::LOCKFILE,
167        description: "Lockfile is structurally invalid — version guard failed, YAML shape is wrong, or `yaml_serde` couldn't round-trip the contents.",
168        exit_code: Some(11),
169    },
170    CodeMeta {
171        name: ERR_AUBE_LOCKFILE_UNSUPPORTED_FORMAT,
172        category: category::LOCKFILE,
173        description: "Lockfile filename was recognized but its format isn't supported on this aube version.",
174        exit_code: Some(12),
175    },
176    CodeMeta {
177        name: ERR_AUBE_RESOLUTION_SHAPE_MISMATCH,
178        category: category::LOCKFILE,
179        description: "A registry-style lockfile dependency path is backed by a git, local directory, or direct tarball resolution.",
180        exit_code: Some(13),
181    },
182    CodeMeta {
183        name: ERR_AUBE_LOCKFILE_CONFIG_MISMATCH,
184        category: category::LOCKFILE,
185        description: "A frozen install found configuration, such as patch-file content, that no longer matches the lockfile.",
186        exit_code: Some(14),
187    },
188    CodeMeta {
189        name: ERR_AUBE_UNSUPPORTED_NAMED_REGISTRY,
190        category: category::LOCKFILE,
191        description: "A pnpm lockfile contains registry-qualified package identities that aube cannot safely resolve yet.",
192        exit_code: Some(15),
193    },
194    // Resolver
195    CodeMeta {
196        name: ERR_AUBE_NO_MATCHING_VERSION,
197        category: category::RESOLVER,
198        description: "No published version of the named package satisfies the requested range.",
199        exit_code: Some(20),
200    },
201    CodeMeta {
202        name: ERR_AUBE_NO_MATURE_MATCHING_VERSION,
203        category: category::RESOLVER,
204        description: "A version satisfying the range exists but every candidate was younger than `minimumReleaseAge` and `minimumReleaseAgeStrict=true`.",
205        exit_code: Some(21),
206    },
207    CodeMeta {
208        name: ERR_AUBE_BLOCKED_EXOTIC_SUBDEP,
209        category: category::RESOLVER,
210        description: "Transitive dep used a `git:` / `file:` / `tarball` specifier and `blockExoticSubdeps=true`.",
211        exit_code: Some(22),
212    },
213    CodeMeta {
214        name: ERR_AUBE_TRUST_DOWNGRADE,
215        category: category::RESOLVER,
216        description: "Picked version dropped trust evidence the prior version had (`trustPolicy=no-downgrade`).",
217        exit_code: Some(23),
218    },
219    CodeMeta {
220        name: ERR_AUBE_TRUST_MISSING_TIME,
221        category: category::RESOLVER,
222        description: "Registry's packument has no `time` entry for the picked version (`trustPolicy=no-downgrade`).",
223        exit_code: Some(24),
224    },
225    CodeMeta {
226        name: ERR_AUBE_UNKNOWN_CATALOG,
227        category: category::RESOLVER,
228        description: "A `catalog:<name>` reference was used but the catalog isn't defined.",
229        exit_code: Some(25),
230    },
231    CodeMeta {
232        name: ERR_AUBE_UNKNOWN_CATALOG_ENTRY,
233        category: category::RESOLVER,
234        description: "The catalog exists but has no entry for the requested package.",
235        exit_code: Some(26),
236    },
237    CodeMeta {
238        name: ERR_AUBE_PEER_CONTEXT_NOT_CONVERGED,
239        category: category::RESOLVER,
240        description: "Peer-context fixed-point loop hit `MAX_ITERATIONS=16` without converging — usually mutually-recursive peers.",
241        exit_code: Some(27),
242    },
243    CodeMeta {
244        name: ERR_AUBE_REGISTRY_ERROR,
245        category: category::RESOLVER,
246        description: "Generic registry error from inside the resolver.",
247        exit_code: None,
248    },
249    CodeMeta {
250        name: ERR_AUBE_TRUST_EXCLUDE_INVALID_VERSION_UNION,
251        category: category::RESOLVER,
252        description: "A `trustPolicyExclude` pattern had an invalid semver range.",
253        exit_code: None,
254    },
255    CodeMeta {
256        name: ERR_AUBE_TRUST_EXCLUDE_NAME_GLOB_WITH_VERSIONS,
257        category: category::RESOLVER,
258        description: "A `trustPolicyExclude` pattern combined a name glob with versions.",
259        exit_code: None,
260    },
261    // Tarball / store
262    CodeMeta {
263        name: ERR_AUBE_TARBALL_INTEGRITY,
264        category: category::TARBALL_STORE,
265        description: "Downloaded tarball's hash didn't match the lockfile's / packument's `dist.integrity`.",
266        exit_code: Some(30),
267    },
268    CodeMeta {
269        name: ERR_AUBE_TARBALL_EXTRACT,
270        category: category::TARBALL_STORE,
271        description: "Tarball couldn't be extracted (corrupt gzip, unexpected entry shape, etc.).",
272        exit_code: Some(31),
273    },
274    CodeMeta {
275        name: ERR_AUBE_PKG_CONTENT_MISMATCH,
276        category: category::TARBALL_STORE,
277        description: "Tarball's `package.json` declared a different `(name, version)` than the resolver expected (`strictStorePkgContentCheck=true`).",
278        exit_code: Some(32),
279    },
280    CodeMeta {
281        name: ERR_AUBE_GIT_ERROR,
282        category: category::TARBALL_STORE,
283        description: "Git operation failed during a `git:` dep prepare or checkout.",
284        exit_code: Some(33),
285    },
286    CodeMeta {
287        name: ERR_AUBE_TARBALL_URL_MISMATCH,
288        category: category::TARBALL_STORE,
289        description: "A registry lockfile entry's explicit tarball URL didn't match the registry metadata for that `(name, version)`.",
290        exit_code: Some(34),
291    },
292    CodeMeta {
293        name: ERR_AUBE_NO_HOME,
294        category: category::TARBALL_STORE,
295        description: "`HOME` (or platform equivalent) is unset, so aube can't locate its store.",
296        exit_code: None,
297    },
298    CodeMeta {
299        name: ERR_AUBE_STORE_INDEX_SCAN_FAILED,
300        category: category::TARBALL_STORE,
301        description: "A store maintenance command couldn't completely read or parse the cached package indexes.",
302        exit_code: None,
303    },
304    CodeMeta {
305        name: ERR_AUBE_GVS_PRUNE_FAILED,
306        category: category::TARBALL_STORE,
307        description: "The global virtual store project registry or prune walk failed.",
308        exit_code: None,
309    },
310    CodeMeta {
311        name: ERR_AUBE_STORE_PRUNE_LOCK_FAILED,
312        category: category::TARBALL_STORE,
313        description: "Aube couldn't acquire the store-wide maintenance lock for pruning.",
314        exit_code: None,
315    },
316    CodeMeta {
317        name: ERR_AUBE_STORE_PRUNE_FAILED,
318        category: category::TARBALL_STORE,
319        description: "A planned content-store file couldn't be removed during pruning.",
320        exit_code: None,
321    },
322    // Registry / network
323    CodeMeta {
324        name: ERR_AUBE_PACKAGE_NOT_FOUND,
325        category: category::REGISTRY_NETWORK,
326        description: "Registry returned 404 for the package name.",
327        exit_code: Some(40),
328    },
329    CodeMeta {
330        name: ERR_AUBE_ACCESS_ENTITY_NOT_FOUND,
331        category: category::REGISTRY_NETWORK,
332        description: "Registry returned 404 for an access user, organization, or team.",
333        exit_code: None,
334    },
335    CodeMeta {
336        name: ERR_AUBE_VERSION_NOT_FOUND,
337        category: category::REGISTRY_NETWORK,
338        description: "Package exists but the requested version doesn't.",
339        exit_code: Some(41),
340    },
341    CodeMeta {
342        name: ERR_AUBE_UNAUTHORIZED,
343        category: category::REGISTRY_NETWORK,
344        description: "Registry returned 401/403 — missing or invalid auth. Run `aube login`.",
345        exit_code: Some(42),
346    },
347    CodeMeta {
348        name: ERR_AUBE_WEB_LOGIN_RESPONSE_TOO_LARGE,
349        category: category::REGISTRY_NETWORK,
350        description: "The web-login token response exceeded the 64 KiB safety limit.",
351        exit_code: None,
352    },
353    CodeMeta {
354        name: ERR_AUBE_OFFLINE,
355        category: category::REGISTRY_NETWORK,
356        description: "Offline mode and the requested resource isn't in the local cache.",
357        exit_code: Some(43),
358    },
359    CodeMeta {
360        name: ERR_AUBE_INVALID_PACKAGE_NAME,
361        category: category::REGISTRY_NETWORK,
362        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.",
363        exit_code: Some(44),
364    },
365    CodeMeta {
366        name: ERR_AUBE_REGISTRY_WRITE_REJECTED,
367        category: category::REGISTRY_NETWORK,
368        description: "Registry rejected a publish/deprecate/owner write with a non-2xx response.",
369        exit_code: Some(45),
370    },
371    CodeMeta {
372        name: ERR_AUBE_MALICIOUS_PACKAGE,
373        category: category::REGISTRY_NETWORK,
374        description: "`aube add` refused a package because OSV reports it as malicious (`MAL-*` advisory). Hard block — confirmed-malicious advisories aren't a judgement call.",
375        exit_code: Some(46),
376    },
377    CodeMeta {
378        name: ERR_AUBE_SIMILAR_PACKAGE_NAME,
379        category: category::SUPPLY_CHAIN,
380        description: "`aube add` refused a package whose name closely resembles a more popular npm package. This protects against typosquatting and slopsquatting.",
381        exit_code: None,
382    },
383    CodeMeta {
384        name: ERR_AUBE_LOW_DOWNLOAD_PACKAGE,
385        category: category::REGISTRY_NETWORK,
386        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.",
387        exit_code: Some(47),
388    },
389    CodeMeta {
390        name: ERR_AUBE_NEW_PACKAGE_NAME,
391        category: category::SUPPLY_CHAIN,
392        description: "`aube add` refused a package name first published within `minimumPackageAge`. This protects against newly registered slopsquatting names.",
393        exit_code: None,
394    },
395    CodeMeta {
396        name: ERR_AUBE_PACKAGE_AGE_CHECK_FAILED,
397        category: category::SUPPLY_CHAIN,
398        description: "`aube add` couldn't verify a package name's registry creation time while `minimumPackageAge` was enabled, so the package-age gate failed closed.",
399        exit_code: None,
400    },
401    CodeMeta {
402        name: ERR_AUBE_ADVISORY_CHECK_FAILED,
403        category: category::REGISTRY_NETWORK,
404        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.",
405        exit_code: Some(49),
406    },
407    CodeMeta {
408        name: ERR_AUBE_SECURITY_SCANNER_FATAL,
409        category: category::SUPPLY_CHAIN,
410        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.",
411        exit_code: Some(48),
412    },
413    CodeMeta {
414        name: ERR_AUBE_SECURITY_SCANNER_FAILED,
415        category: category::SUPPLY_CHAIN,
416        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.",
417        exit_code: None,
418    },
419    // Scripts / build
420    CodeMeta {
421        name: ERR_AUBE_SCRIPT_NON_ZERO_EXIT,
422        category: category::SCRIPTS,
423        description: "A lifecycle script (`preinstall` / `install` / `postinstall` / a `package.json` script) exited non-zero.",
424        exit_code: Some(50),
425    },
426    CodeMeta {
427        name: ERR_AUBE_SCRIPT_SPAWN,
428        category: category::SCRIPTS,
429        description: "Couldn't spawn a script's interpreter (shell missing, jail setup failed, etc.).",
430        exit_code: Some(51),
431    },
432    CodeMeta {
433        name: ERR_AUBE_BUILD_POLICY_UNSUPPORTED_VALUE,
434        category: category::SCRIPTS,
435        description: "An entry in `allowBuilds` had a value that wasn't `true`/`false`.",
436        exit_code: None,
437    },
438    CodeMeta {
439        name: ERR_AUBE_BUILD_POLICY_INVALID_VERSION_UNION,
440        category: category::SCRIPTS,
441        description: "An `allowBuilds` pattern's version union was unparseable.",
442        exit_code: None,
443    },
444    CodeMeta {
445        name: ERR_AUBE_BUILD_POLICY_WILDCARD_WITH_VERSION,
446        category: category::SCRIPTS,
447        description: "An `allowBuilds` pattern combined a wildcard name with a version union.",
448        exit_code: None,
449    },
450    // Linker
451    CodeMeta {
452        name: ERR_AUBE_PATCH_FAILED,
453        category: category::LINKER,
454        description: "Applying a `pnpm.patchedDependencies` patch failed.",
455        exit_code: Some(60),
456    },
457    CodeMeta {
458        name: ERR_AUBE_LINK_FAILED,
459        category: category::LINKER,
460        description: "Symlink / junction / hardlink couldn't be created — usually permissions or filesystem support.",
461        exit_code: Some(61),
462    },
463    CodeMeta {
464        name: ERR_AUBE_MISSING_PACKAGE_INDEX,
465        category: category::LINKER,
466        description: "Internal: a caller skipped `load_index` but the package wasn't already materialized.",
467        exit_code: Some(62),
468    },
469    CodeMeta {
470        name: ERR_AUBE_MISSING_STORE_FILE,
471        category: category::LINKER,
472        description: "A package index references a CAS shard that doesn't exist on disk. Re-run install to re-fetch.",
473        exit_code: Some(63),
474    },
475    CodeMeta {
476        name: ERR_AUBE_UNSAFE_MODULES_DIR,
477        category: category::LINKER,
478        description: "The configured modules directory resolves to the project root or outside it, where linker cleanup could remove unrelated files.",
479        exit_code: Some(64),
480    },
481    // Manifest / workspace
482    CodeMeta {
483        name: ERR_AUBE_MANIFEST_PARSE,
484        category: category::MANIFEST_WORKSPACE,
485        description: "A `package.json` had a syntax error. miette renders a pointer at the offending byte.",
486        exit_code: Some(70),
487    },
488    CodeMeta {
489        name: ERR_AUBE_WORKSPACE_PARSE,
490        category: category::MANIFEST_WORKSPACE,
491        description: "An `aube-workspace.yaml` / `pnpm-workspace.yaml` was structurally invalid.",
492        exit_code: Some(71),
493    },
494    CodeMeta {
495        name: ERR_AUBE_MANIFEST_YAML_PARSE,
496        category: category::MANIFEST_WORKSPACE,
497        description: "A workspace YAML helper file was structurally invalid (no source pointer available).",
498        exit_code: None,
499    },
500    CodeMeta {
501        name: ERR_AUBE_INVALID_PACKAGE_EXTENSION,
502        category: category::MANIFEST_WORKSPACE,
503        description: "A `packageExtensions` entry had an invalid object shape or non-string dependency range.",
504        exit_code: None,
505    },
506    CodeMeta {
507        name: ERR_AUBE_FILTER_EMPTY,
508        category: category::MANIFEST_WORKSPACE,
509        description: "`--filter` was passed an empty selector.",
510        exit_code: None,
511    },
512    CodeMeta {
513        name: ERR_AUBE_FILTER_GIT_IO,
514        category: category::MANIFEST_WORKSPACE,
515        description: "A `--filter ...[ref]` selector failed to spawn `git`.",
516        exit_code: None,
517    },
518    CodeMeta {
519        name: ERR_AUBE_FILTER_GIT_FAILED,
520        category: category::MANIFEST_WORKSPACE,
521        description: "The git subprocess for a `--filter ...[ref]` selector exited non-zero.",
522        exit_code: None,
523    },
524    // Engine / CLI
525    CodeMeta {
526        name: ERR_AUBE_UNSUPPORTED_ENGINE,
527        category: category::ENGINE_CLI,
528        description: "One or more packages declared an `engines` constraint incompatible with the running Node/aube and `engine-strict=true`.",
529        exit_code: Some(80),
530    },
531    CodeMeta {
532        name: ERR_AUBE_UNKNOWN_COMMAND,
533        category: category::ENGINE_CLI,
534        description: "The named subcommand isn't a built-in aube command and isn't a script in the manifest.",
535        exit_code: Some(81),
536    },
537    CodeMeta {
538        name: ERR_AUBE_NPM_ONLY_COMMAND,
539        category: category::ENGINE_CLI,
540        description: "The user invoked an npm-only command (`whoami`, `token`, `owner`, `search`, `pkg`, `set-script`) — aube doesn't implement these; use npm.",
541        exit_code: Some(82),
542    },
543    CodeMeta {
544        name: ERR_AUBE_RECURSIVE_NOT_SUPPORTED,
545        category: category::ENGINE_CLI,
546        description: "A command was invoked under `--recursive` but doesn't support recursive execution.",
547        exit_code: None,
548    },
549    CodeMeta {
550        name: ERR_AUBE_COMPLETION_FAILED,
551        category: category::ENGINE_CLI,
552        description: "`aube completion` couldn't invoke `usage` to render the shell completions.",
553        exit_code: None,
554    },
555    CodeMeta {
556        name: ERR_AUBE_USAGE_SPEC_WRITE_FAILED,
557        category: category::ENGINE_CLI,
558        description: "`aube usage` couldn't write the CLI spec to stdout; the output would have been truncated.",
559        exit_code: None,
560    },
561    CodeMeta {
562        name: ERR_AUBE_REMOVE_PRIOR_INSTALL_DIR,
563        category: category::ENGINE_CLI,
564        description: "Couldn't clean up a prior global install dir before re-installing.",
565        exit_code: None,
566    },
567    CodeMeta {
568        name: ERR_AUBE_CONFIG_NESTED_AUBE_KEY,
569        category: category::ENGINE_CLI,
570        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.",
571        exit_code: None,
572    },
573    CodeMeta {
574        name: ERR_AUBE_CONFLICTING_BUILD_FLAGS,
575        category: category::ENGINE_CLI,
576        description: "`aube add` was passed the same package name in both `--allow-build` and `--deny-build`.",
577        exit_code: None,
578    },
579    CodeMeta {
580        name: ERR_AUBE_ACCESS_INVALID_ARGUMENT,
581        category: category::ENGINE_CLI,
582        description: "`aube access` received an invalid access setting, permission level, team, or package argument.",
583        exit_code: None,
584    },
585    CodeMeta {
586        name: ERR_AUBE_PUBLISH_SOURCE_NOT_FOUND,
587        category: category::ENGINE_CLI,
588        description: "`aube publish` was given a package directory or tarball path that doesn't exist.",
589        exit_code: None,
590    },
591    CodeMeta {
592        name: ERR_AUBE_SHIM_CREATE_FAILED,
593        category: category::ENGINE_CLI,
594        description: "`aube activate <shell>` couldn't create or refresh an executable shim in aube's shim directory.",
595        exit_code: None,
596    },
597    CodeMeta {
598        name: ERR_AUBE_SHIM_EXEC_FAILED,
599        category: category::ENGINE_CLI,
600        description: "A runtime tool shim resolved its target but couldn't exec or spawn the selected tool.",
601        exit_code: None,
602    },
603    // Node runtime (devEngines.runtime / .node-version / .nvmrc)
604    CodeMeta {
605        name: ERR_AUBE_RUNTIME_VERSION_UNSATISFIED,
606        category: category::ENGINE_CLI,
607        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).",
608        exit_code: Some(83),
609    },
610    CodeMeta {
611        name: ERR_AUBE_RUNTIME_NO_MATCHING_VERSION,
612        category: category::ENGINE_CLI,
613        description: "No Node.js release in the dist index satisfies the requested version (bad range, unknown LTS codename, or no build for this platform).",
614        exit_code: Some(84),
615    },
616    CodeMeta {
617        name: ERR_AUBE_RUNTIME_DOWNLOAD_FAILED,
618        category: category::ENGINE_CLI,
619        description: "Fetching the Node.js dist index, checksum file, or release archive failed after retries.",
620        exit_code: Some(85),
621    },
622    CodeMeta {
623        name: ERR_AUBE_RUNTIME_CHECKSUM_MISMATCH,
624        category: category::ENGINE_CLI,
625        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.",
626        exit_code: Some(86),
627    },
628    CodeMeta {
629        name: ERR_AUBE_RUNTIME_EXTRACT_FAILED,
630        category: category::ENGINE_CLI,
631        description: "A Node.js release archive was corrupt or contained unsafe entry paths.",
632        exit_code: Some(87),
633    },
634    CodeMeta {
635        name: ERR_AUBE_RUNTIME_MISE_INSTALL_FAILED,
636        category: category::ENGINE_CLI,
637        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.",
638        exit_code: Some(88),
639    },
640    CodeMeta {
641        name: ERR_AUBE_RUNTIME_UNSUPPORTED_PLATFORM,
642        category: category::ENGINE_CLI,
643        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.",
644        exit_code: Some(89),
645    },
646    CodeMeta {
647        name: ERR_AUBE_RUNTIME_IO,
648        category: category::ENGINE_CLI,
649        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.",
650        exit_code: None,
651    },
652    CodeMeta {
653        name: ERR_AUBE_SELF_UPDATE_UNSUPPORTED_PLATFORM,
654        category: category::ENGINE_CLI,
655        description: "`aube self-update` has no published aube release archive for this OS/architecture (e.g. FreeBSD, Intel macOS). Install aube via your system package manager or mise. Distinct from ERR_AUBE_RUNTIME_UNSUPPORTED_PLATFORM, which is about the Node.js download.",
656        exit_code: None,
657    },
658    // Misc / safety
659    CodeMeta {
660        name: ERR_AUBE_INSTALL_CANCELLED,
661        category: category::MISC_SAFETY,
662        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.",
663        exit_code: None,
664    },
665    CodeMeta {
666        name: ERR_AUBE_UNSAFE_INDEX_KEY,
667        category: category::MISC_SAFETY,
668        description: "A package index key tried to escape its directory (path traversal defense in depth).",
669        exit_code: Some(90),
670    },
671    CodeMeta {
672        name: ERR_AUBE_UNSAFE_SHEBANG_INTERPRETER,
673        category: category::MISC_SAFETY,
674        description: "A `#!` shebang named an unsafe interpreter when generating a shim — substituted with `node` instead. Surfaced as `tracing::error!` but install continues.",
675        exit_code: Some(91),
676    },
677    CodeMeta {
678        name: ERR_AUBE_EMBED_INVALID_PROJECT,
679        category: category::MISC_SAFETY,
680        description: "An in-process embedder was given a project directory that could not be created, inspected, or resolved.",
681        exit_code: None,
682    },
683    CodeMeta {
684        name: ERR_AUBE_EMBED_INSTALL_FAILED,
685        category: category::MISC_SAFETY,
686        description: "An in-process embedder could not initialize its host callback or received an install failure without a more specific stable code.",
687        exit_code: None,
688    },
689    CodeMeta {
690        name: ERR_AUBE_EMBED_INVALID_SETTING,
691        category: category::MISC_SAFETY,
692        description: "An in-process embedder passed a setting default whose name is not a canonical aube setting.",
693        exit_code: None,
694    },
695    CodeMeta {
696        name: ERR_AUBE_EMBED_ALREADY_INITIALIZED,
697        category: category::MISC_SAFETY,
698        description: "An in-process embedder tried to register setting defaults after the process already initialized its embedder profile.",
699        exit_code: None,
700    },
701    CodeMeta {
702        name: ERR_AUBE_FFI_INVALID_ARGUMENT,
703        category: category::MISC_SAFETY,
704        description: "A C ABI call received a null pointer, invalid UTF-8, malformed JSON, or an unsupported option value.",
705        exit_code: None,
706    },
707    CodeMeta {
708        name: ERR_AUBE_FFI_UNKNOWN_HANDLE,
709        category: category::MISC_SAFETY,
710        description: "A C ABI wait or cancellation call referenced an unknown or already-consumed operation handle.",
711        exit_code: None,
712    },
713    CodeMeta {
714        name: ERR_AUBE_FFI_RUNTIME,
715        category: category::MISC_SAFETY,
716        description: "The C ABI could not initialize or use its internal asynchronous runtime.",
717        exit_code: None,
718    },
719    CodeMeta {
720        name: ERR_AUBE_FFI_PANIC,
721        category: category::MISC_SAFETY,
722        description: "A panic was caught at the C ABI boundary before it could cross into the host process.",
723        exit_code: None,
724    },
725    CodeMeta {
726        name: ERR_AUBE_UNSAFE_PACKAGE_NAME,
727        category: category::MISC_SAFETY,
728        description: "A package/dependency alias would escape its `node_modules` slot if linked.",
729        exit_code: Some(92),
730    },
731    CodeMeta {
732        name: ERR_AUBE_PATCHES_TRACKING_WRITE,
733        category: category::MISC_SAFETY,
734        description: "Couldn't write `.aube-applied-patches.json` after applying patches. Non-fatal; next install may miss stale patched entries.",
735        exit_code: None,
736    },
737];