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