> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blobhub.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Error codes

> Every code the CLI can raise, what it means, and what to do about it

Every error the CLI can raise carries a stable code, a human message, and — where one exists — a hint that is a
runnable command **or a code fragment** you can paste; a remediation that can only be described in words has no
hint and lives in the message instead. Human output is `error: <CODE>: <message>` on stderr, followed by
`hint: <command>` when a hint is set. `--json` emits `{"error", "hint", "code", "schema_version"}` on stderr
instead. The exit code is always `1` for these; `0` is success and `2` is a usage error (unknown flag, missing
required option).

Where a remediation below shows `<group>`, the binary substitutes the group of the command you ran —
`blobhub workflow diff -f <path>` for a workflow manifest, `blobhub scheduler diff -f <path>` for a scheduler one.
A hint is contractually a command you can paste, and one that named `workflow` unconditionally would answer
`MANIFEST_TYPE_MISMATCH` when pasted against a scheduler manifest.

[`blobhub completion`](/cli/utilities#blobhub-completion) is the one command exempt from `--json`: its output is a
shell script meant to be piped into a file, and wrapping it in an envelope would make the only use of the command
impossible.

Advisories are a separate, non-fatal category: printed as `warning: <CODE>: <message>` on stderr, suppressed under
`-q` and whenever stderr is not a TTY, so piping and CI logs stay quiet unless a real terminal is attached. They
never change a command's exit code, and no flag brings a suppressed one back — see [Advisories](#advisories).

This page mirrors the CLI's own error-code reference, and is checked against the binary's catalog in both
directions: it can neither name a code the CLI cannot raise nor omit one it can. Where that reference has fallen
behind the binary, this page states what the binary does and records the difference under
[Where this page diverges from the CLI reference](#where-this-page-diverges-from-the-cli-reference).

## Credentials and authentication

| Code                               | Meaning                                                                                              | Remediation                                                                         |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `CREDENTIALS_NOT_FOUND`            | No credentials file, the named profile is absent, or the file failed to parse.                       | Run [`blobhub login`](/cli/auth#blobhub-login).                                     |
| `INSECURE_CREDENTIALS_PERMISSIONS` | `~/.blobhub/credentials.yaml` has group or other permission bits set.                                | `chmod 600 ~/.blobhub/credentials.yaml` — the CLI never auto-fixes this.            |
| `AUTH_INVALID`                     | The API key was rejected by `GET /v1/users/me`, or no key was supplied at login.                     | Run [`blobhub login`](/cli/auth#blobhub-login), optionally with `--profile <name>`. |
| `PROFILE_NOT_FOUND`                | `--profile` (or `BLOBHUB_PROFILE=<name>`, or a stored `default`) names a profile that doesn't exist. | Run [`blobhub profile ls`](/cli/auth#blobhub-profile-ls) to see what's stored.      |

## API transport

| Code                  | Meaning                                                                                           | Remediation                                                     |
| --------------------- | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `API_RATE_LIMITED`    | HTTP 429; retried with full jitter before surfacing — three attempts in all, so two retries.      | Retry the command; back off if it recurs.                       |
| `API_TRANSIENT_ERROR` | HTTP 5xx or a non-JSON body; retried the same way.                                                | Retry the command.                                              |
| `API_NETWORK_ERROR`   | The request never reached the server (DNS, connection, timeout); retried the same way.            | Check connectivity and retry.                                   |
| `API_COMMAND_FAILED`  | The server returned `status: "failure"` with an error string the CLI has no specific mapping for. | Re-run with `-v` to see the request and the server's raw error. |

## Manifest

| Code                           | Meaning                                                                                                                                                                                                                                                                                                              | Remediation                                                                                                                                |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `MANIFEST_NOT_FOUND`           | The manifest file at `-f/--file` does not exist.                                                                                                                                                                                                                                                                     | Check the path, or run `blobhub <group> diff -f <path>` once it does.                                                                      |
| `MANIFEST_INVALID`             | The manifest failed schema validation: a missing/wrong-typed field, malformed component binding, a referenced source file missing at `push`/`build`/`deploy` time, a bare `blob:` name with no org from `--org`/`BLOBHUB_ORG=<org>`, or a `blob:` value unusable as an allowlist cache key (`..`, an absolute path). | `blobhub <group> diff -f <path>` to see what's readable, then fix the YAML/JSON. The bare-name case names all three ways to supply an org. |
| `MANIFEST_TYPE_MISMATCH`       | The manifest's `type:` is not the one the loading group expects: `workflow_blob_deployment` for the `workflow` group, `scheduler_blob_deployment` for `scheduler`.                                                                                                                                                   | Edit `type:` in the manifest, or run the group that matches the type already there.                                                        |
| `MANIFEST_VERSION_UNSUPPORTED` | The manifest's `version:` is not one this CLI build understands.                                                                                                                                                                                                                                                     | Upgrade the CLI, or pin the manifest to a supported version.                                                                               |

## Blob and revision

| Code                      | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                               | Remediation                                                                                                                                                                                                                                       |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BLOB_REFERENCE_INVALID`  | A positional `<org/blob>` argument is empty, has more than one `/`, has an empty segment either side of the `/` (`/flow`, `acme/`), or is a bare name with no org available from `--org` or `BLOBHUB_ORG=<org>`.                                                                                                                                                                                                                                      | Qualify it as `<org>/<name>`, pass `--org <org>`, or set `BLOBHUB_ORG=<org>`. The hint names the command you ran.                                                                                                                                 |
| `BLOB_NOT_ACCESSIBLE`     | The blob is absent or not reachable with this key — the platform returns the same 403 for both, so the message cannot distinguish them. If the org segment isn't a UUID, the message also notes that an org-scoped key must address the org by UUID, not the alias.                                                                                                                                                                                   | Run [`blobhub whoami`](/cli/auth#blobhub-whoami) to confirm identity and scope.                                                                                                                                                                   |
| `BLOB_NOT_WORKFLOW`       | The blob's `domain`/`type`/`format` is not the shape the command's group expects — `workflow`/`generic`/`blobhub` for the `workflow` group, `scheduler`/`generic`/`blobhub` for `scheduler`. The message names both the shape found and the shape expected. Despite the name, this is not a workflow-only code: one shared resolver raises it for every group, and the name is kept as published so a `--json` consumer matching on it keeps working. | Point the manifest at a blob of the group's own shape; there is no conversion path.                                                                                                                                                               |
| `LIMITS_NOT_ACCESSIBLE`   | `GET /blobs/{org}/{blob}/limits` requires an `admin`-scoped key; this key is not one, or the blob is not reachable.                                                                                                                                                                                                                                                                                                                                   | Run [`blobhub whoami`](/cli/auth#blobhub-whoami) to check the key's scope, and retry with an admin key. The `read`/`write` keys recommended for automation cannot read limits.                                                                    |
| `REVISION_NOT_ACCESSIBLE` | The revision is absent or not reachable with this key.                                                                                                                                                                                                                                                                                                                                                                                                | `blobhub <group> diff -f <path>` once access is restored.                                                                                                                                                                                         |
| `REVISION_NOT_WRITABLE`   | The revision's status isn't `ready`, or its phase isn't one of the allowed phases for the operation (writes need `draft`/`managed`; reads also allow `commit`). The message names the actual phase and status.                                                                                                                                                                                                                                        | `blobhub <group> diff -f <path>`, with the allowed phases appended to the hint as a trailing comment; [`blobhub blob revisions <org>/<blob>`](/cli/blob/revisions) lists every revision with its phase, so you can pin one the operation accepts. |

## Definitions

| Code                          | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                           | Remediation                                                                                                                       |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `DEFINITION_NOT_ACCESSIBLE`   | A `--definition <alias>` names an alias that isn't in the manifest.                                                                                                                                                                                                                                                                                                                                                                               | Check the alias against the manifest's `definitions[]`.                                                                           |
| `DEFINITION_ALIAS_INVALID`    | A manifest entry's `alias` fails `^[a-z0-9_-]{6,42}$`.                                                                                                                                                                                                                                                                                                                                                                                            | Rename the alias in the manifest to match the pattern.                                                                            |
| `DEFINITION_CATEGORY_UNKNOWN` | Either a definition file's own `type` isn't a recognized native category (`workflow_definition`/`playground_definition`) and the manifest entry declares no `category:` to disambiguate, or a declared `category:` contradicts the document's `type`. Nothing server-side catches the contradiction — workflow uploads validate nothing at all — so a playground document declared as a workflow would upload into the wrong definition silently. | Add an explicit `category:` to the manifest entry, or fix whichever of the two is wrong.                                          |
| `ALIAS_IN_USE`                | The server rejected a `create_definition`/rename because the alias is already taken on this revision.                                                                                                                                                                                                                                                                                                                                             | Choose a different alias, or target the existing one instead of creating.                                                         |
| `LIMIT_EXCEEDED`              | The revision is already at its per-category definition cap.                                                                                                                                                                                                                                                                                                                                                                                       | Remove an unused definition first, or request a higher limit.                                                                     |
| `PRUNE_NOT_CONFIRMED`         | `workflow prune` was run without a terminal to prompt on and without `--yes`, so it refused rather than deleting unattended or blocking forever on a pipe.                                                                                                                                                                                                                                                                                        | Re-run with `--yes` in automation, or from a terminal to confirm interactively. `--dry-run` shows what would go without deleting. |

## Format

| Code                 | Meaning                                                     | Remediation                                                                 |
| -------------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------- |
| `FORMAT_UNSUPPORTED` | A file's extension is neither `.json`, `.yaml`, nor `.yml`. | Rename the file to a supported extension.                                   |
| `FORMAT_PARSE_ERROR` | The file has a supported extension but failed to parse.     | Fix the JSON/YAML syntax; the message includes the underlying parser error. |

## Entry points and imports

| Code                       | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                             | Remediation                                                                                                                                                                                 |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ENTRY_POINT_NOT_FOUND`    | The manifest's `entry_point` doesn't exist under `base_path`. The message names both.                                                                                                                                                                                                                                                                                                                                                               | Fix the `entry_point`/`base_path` pair in the manifest. No hint: that remediation is prose, not a command.                                                                                  |
| `BASE_PATH_ESCAPE`         | A module resolves outside `base_path` — a relative import (`from .. import x`) climbing past it, or an `entry_point` that isn't under it in the first place.                                                                                                                                                                                                                                                                                        | Restructure the package so every module stays under `base_path`, or fix the `entry_point`/`base_path` pair.                                                                                 |
| `IMPORT_UNAVAILABLE`       | An import is neither local, sandbox pre-bound, nor on the (readable) allowlist.                                                                                                                                                                                                                                                                                                                                                                     | The message names the import and, on `deploy`, appends what the allowlist currently permits; there is no hint, because a list of permitted modules is prose rather than something to paste. |
| `IMPORT_NAME_NOT_FOUND`    | A `from x import <name>` targets a confirmed-local module or package that never defines `<name>`. Always fatal, never an advisory: it is decided offline by parsing a file already on disk, so an unreadable allowlist says nothing about it.                                                                                                                                                                                                       | Fix the typo, or add the missing definition to the target module.                                                                                                                           |
| `IMPORT_CYCLE`             | Two or more local modules import each other, directly or transitively.                                                                                                                                                                                                                                                                                                                                                                              | The message names the cycle; break it by removing or restructuring one of the imports.                                                                                                      |
| `SYMBOL_COLLISION`         | Two inlined local modules both define the same top-level name. **Conditional imports report as this:** `try: from a import helper / except ImportError: from b import helper` walks and inlines *both* branches — the compiler never evaluates which one would win — so the two definitions of `helper` collide, and the message names two modules without mentioning the `try`.                                                                    | The message names both modules; rename one of the colliding definitions, or drop the fallback branch (the sandbox has no `__import__`, so `ImportError` can never fire there anyway).       |
| `SANDBOX_NAME_SHADOWED`    | An inlined local module redefines a name the sandbox pre-binds (`result`, `set_result`, `data_inputs`, `Exit`, …). The reserved set is the builtins, the platform helpers, the typing names and the exception names — **not** the pre-bound stdlib modules. A top-level `json` is therefore not this code: it compiles silently. A local module *file* named `json.py` is the related [`LOCAL_SHADOWS_SANDBOX_MODULE`](#advisories) advisory below. | The message names the shadowed name; rename the local definition.                                                                                                                           |
| `LOCAL_MODULE_IMPORT_FORM` | An import names a local *module* where the flat namespace can only ever bind names *inside* it: the dotted `import pkg.mod` form, or `from pkg import mod` / `from . import mod` where `mod` is a sibling submodule file. Inlining flattens that file's contents and never binds `mod`, so every `mod.thing` afterwards would be a `NameError` at runtime.                                                                                          | The hint shows the working form for the statement as written — `from pkg.mod import <name>`, or `from .mod import <name>` for the relative one.                                             |
| `UNSUPPORTED_IMPORT_FORM`  | `from x import *` against a non-local `x` — its exported names can't be statically enumerated to rebind them in the flattened namespace.                                                                                                                                                                                                                                                                                                            | Replace the wildcard with the explicit names you use: `from x import a, b`.                                                                                                                 |

## Components

| Code                       | Meaning                                                                                                                                                  | Remediation                                                                                                                                                                                                                                                                                                                                                                                           |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `COMPONENT_NOT_FOUND`      | A manifest component binding's `id`/`name` matches no component in the definition document.                                                              | Check the binding against the definition's actual `components[]`.                                                                                                                                                                                                                                                                                                                                     |
| `COMPONENT_NAME_AMBIGUOUS` | A binding by `name` matches more than one component.                                                                                                     | Bind by `id` instead, or rename the components so the name is unique.                                                                                                                                                                                                                                                                                                                                 |
| `COMPONENT_PORT_MISSING`   | The bound component has no `code`/`value` port at the route the binding expects.                                                                         | Check the component's `ports[]` in the definition document.                                                                                                                                                                                                                                                                                                                                           |
| `LANGUAGE_NOT_PYTHON`      | A `code` binding's component has a `language` port that isn't the choice value `python`.                                                                 | Only Python components can hold CLI-managed code; point the binding elsewhere.                                                                                                                                                                                                                                                                                                                        |
| `REMOTE_EDIT`              | The embedded code's hash no longer matches its recorded `content_hash` — it was edited outside the CLI (e.g. in the visual editor) since the last build. | Re-run `blobhub workflow build`/`deploy` with `--force` to overwrite it, or run `blobhub workflow eject` to pull the remote edit onto disk and reconcile it by hand first. `eject` is not the inverse of `build` — see its own row below.                                                                                                                                                             |
| `UNMANAGED_CODE`           | The code port has content but no recorded `content_hash` at all — it was never built by this CLI.                                                        | Re-run `blobhub workflow build`/`deploy` with `--force` to overwrite it, or run `blobhub workflow eject` first. Same caveat as `REMOTE_EDIT`.                                                                                                                                                                                                                                                         |
| `EJECT_TARGET_EXISTS`      | `workflow eject` would overwrite a file that already exists on disk.                                                                                     | Re-run with `--force` to overwrite — that is what the hint offers. `--output <dir>` is an alternative only for a component with **no** `code:` binding; on a bound one it is refused with `MANIFEST_INVALID`, because two roots for one component is how the package ends up in two places while `build` keeps compiling the one you stopped editing. Every conflicting path is named in the message. |

## Playground

| Code                          | Meaning                                                                                                                                               | Remediation                                                                                      |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `PLAYGROUND_LAYOUT_IMMUTABLE` | The server rejected an upload because the playground's `layout` differs from what was canonicalized at creation (a missing `layout` also fails this). | `blobhub workflow pull` to get the current, authoritative `layout`, then round-trip it verbatim. |
| `PLAYGROUND_POSITION_INVALID` | A component's grid position exceeds the layout's `columns` (`x + width > columns`).                                                                   | The message names the component; fix its `position` in the definition document.                  |

## Checks

| Code           | Meaning                                                                                          | Remediation                                                                                                                                          |
| -------------- | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CHECK_FAILED` | `check_definition` returned body `status: "failure"` (a `200` HTTP status can still carry this). | The message includes the checker's events (missing `flow.start`, dangling connections, unknown component types, …); fix the definition and re-check. |

## Sessions and executions

| Code                        | Meaning                                                                                                                                           | Remediation                                                                                                                     |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `SESSION_NOT_ACCESSIBLE`    | A session id was given that is absent or not reachable with this key. Ids are server-assigned, so unlike an alias it cannot be created on demand. | Run `blobhub workflow execute` with `--session <alias>` to find-or-create by name, or omit `--session` for a fresh one.         |
| `SESSION_NOT_OPEN`          | The target session is closed, closing, or deleting; the platform refuses to create an execution on it.                                            | Reopen the session in the web UI, or pass a different `--session` — the CLI will not reopen it for you.                         |
| `DEFINITION_NOT_EXECUTABLE` | The named definition is a `playground`, and the platform executes `workflow` definitions only.                                                    | Pass `--definition <alias>` naming a workflow definition; `blobhub workflow ls -f <manifest>` shows each definition's category. |
| `EXECUTION_FAILED`          | `--watch` followed the execution to a terminal `failed` status.                                                                                   | The events printed above the error are the platform's own account of the failure; `--open` shows the same run in the debugger.  |

## Schedules

| Code                      | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Remediation                                                                                                                                  |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `SCHEDULE_ALIAS_REQUIRED` | A `scheduler_blob_deployment` manifest entry has no `alias`. The message names the offending index — alias is the manifest's identity for a schedule, so an aliasless entry can never be addressed declaratively and every `deploy` would duplicate it.                                                                                                                                                                                                                                            | Add a unique `alias` to the schedule entry named in the message.                                                                             |
| `SCHEDULE_ALIAS_INVALID`  | A `scheduler_blob_deployment` manifest entry's `alias` fails `^[a-z0-9_-]{6,42}$`, the platform's own schedule-alias grammar. Checked at load rather than left to the server's `400`, because a manifest whose *second* entry has a bad alias would otherwise deploy the first and then fail, leaving a half-deployed set already firing on its cron.                                                                                                                                              | Rename the alias in the manifest to match the pattern.                                                                                       |
| `SCHEDULE_TARGET_INVALID` | A schedule entry's target does not resolve or is unreachable: the target blob, its revision, or the `workflow:` alias (checked against the revision's `workflow`-category definitions only — a `playground` alias of the same name does not count). The message names the offending blob or alias. A target `session:` that fails to resolve is a *separate* failure — `SESSION_NOT_ACCESSIBLE`/`SESSION_NOT_OPEN` under [Sessions and executions](#sessions-and-executions) above, not this code. | Fix the target's `blob`/`revision`/`workflow` in the manifest, or restore the workflow definition if it was renamed or removed.              |
| `SCHEDULE_NOT_ACCESSIBLE` | `deploy` addressed a schedule `list_schedules` had just returned, and `update_schedule` reports it gone — deleted concurrently, or no longer reachable with this key.                                                                                                                                                                                                                                                                                                                              | Re-run `blobhub scheduler deploy -f <manifest>`; if it recurs, run `blobhub scheduler ls -f <manifest>` to see the schedule's current state. |

## Advisories

Non-fatal, printed as `warning: <CODE>: <message>`, suppressed under `-q` and when stderr is not a TTY.

**`-v` does not bring a suppressed advisory back**, and no other flag does either — so an advisory is unobservable
from automation: suppressed on a pipe, absent from the `--json` payload, visible only on a terminal. That bites
hardest on `DEFINITION_LIST_TRUNCATED` and `IMPORT_UNVERIFIED`, each of which says a run may have acted on
incomplete information, so where one would change what you do, reach instead for the flag that turns its
condition into a hard failure — `workflow build --strict-imports` promotes `IMPORT_UNVERIFIED` to a refusal. See
[Advisories](/cli/configuration#advisories) for why verbosity and advisories are separate channels.

| Code                           | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEFINITION_LIST_TRUNCATED`    | `list_definitions` returned a count matching the revision's configured per-category maximum — the platform has no pagination on this listing, so results may be silently incomplete. Only fires when the caller's key can read limits. `scheduler diff`/`deploy` also raise it when a schedule target's `workflow:` alias is absent from a listing that has reached that cap: absent and past-the-cut-off are the same observation, so the alias is left for the platform to resolve at write time rather than failing a manifest that may well be valid. |
| `REVISION_LIST_TRUNCATED`      | `list_revisions` returned a count matching the blob's configured `revisions_per_blob` maximum — the platform has no pagination on this listing, so results may be silently incomplete. Only fires when the caller's key can read limits.                                                                                                                                                                                                                                                                                                                  |
| `ALLOWLIST_UNREADABLE`         | No cached allowlist exists and the live read (when attempted) was refused — unresolved imports degrade to `IMPORT_UNVERIFIED` instead of a hard failure.                                                                                                                                                                                                                                                                                                                                                                                                  |
| `ALLOWLIST_STALE`              | The cached allowlist is more than 7 days old.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `ALLOWLIST_ENTRY_UNUSABLE`     | An allowlist entry isn't a valid Python identifier (e.g. a dotted name like `numpy.linalg`) and therefore can never be bound in sandboxed code.                                                                                                                                                                                                                                                                                                                                                                                                           |
| `ALLOWLIST_SHADOWS_SANDBOX`    | An allowlist entry collides with a name the sandbox pre-binds; the allowlisted module wins at runtime, exactly as the platform's own merge order does.                                                                                                                                                                                                                                                                                                                                                                                                    |
| `IMPORT_UNVERIFIED`            | An import can't be classified because no allowlist could be read (degraded form of `IMPORT_UNAVAILABLE`); `--strict-imports` promotes this to a hard failure.                                                                                                                                                                                                                                                                                                                                                                                             |
| `DEFINITION_SIZE_NEAR_LIMIT`   | A compiled definition document is at or past 80% of the platform's 10 MB payload ceiling.                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `LOCAL_SHADOWS_SANDBOX_MODULE` | A local module's name matches a sandbox pre-bound stdlib module (e.g. a local `re.py`); local resolution wins, exactly as the sandbox's own merge order would.                                                                                                                                                                                                                                                                                                                                                                                            |
| `SCOPE_UNVERIFIED`             | [`whoami`](/cli/auth#blobhub-whoami)'s scope probe (`GET /users/me/orgs`) failed for a reason other than a `403`, so the key's scope is reported as `unknown`. The key itself is fine — it already authenticated — and every other command is unaffected.                                                                                                                                                                                                                                                                                                 |
| `EXECUTION_WATCH_TIMEOUT`      | `--watch` stopped tailing before the execution reached a terminal status. The execution is still running on the platform and is unaffected; only the tail gave up.                                                                                                                                                                                                                                                                                                                                                                                        |
| `SESSION_NEAR_SATURATION`      | A `recurring_cron` schedule's target session already carries more executions than `deploy`'s saturation threshold — `workflow_executions_per_session` is enforced at creation, so every future fire will eventually start failing silently with an `invocation_error`. Counting stops as soon as it is proven, so the count in the message is exact only up to that point. Names the platform's configured maximum only when limits happen to be readable; `one_time` schedules never trigger this, since one more execution cannot saturate anything.    |

## Where this page diverges from the CLI reference

This page is a mirror of `docs/reference/error-codes.md` in the CLI repository. That file predates two releases of
the binary, and a little of what it says never held. Every claim the binary contradicts is stated here as the
binary behaves, and listed below so the difference reads as staleness in the source rather than drift in this
page. Each is logged for repair upstream.

| Upstream line                | What it says                                                                                 | What the binary does                                                                                                                                                                                                                                                                                                                                                                                                        |
| ---------------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `error-codes.md:33`          | `API_RATE_LIMITED` is "retried three times".                                                 | `_ATTEMPTS = 3` in `api/client.py` counts attempts, not retries: three attempts, so two retries.                                                                                                                                                                                                                                                                                                                            |
| `error-codes.md:44`          | `MANIFEST_TYPE_MISMATCH` is raised when `type:` is not `workflow_blob_deployment`.           | The scheduler loader raises the same code for a `type:` that is not `scheduler_blob_deployment`.                                                                                                                                                                                                                                                                                                                            |
| `error-codes.md:42,43,55,56` | Four remediations hardcode `blobhub workflow diff -f <path>`.                                | Every one of those hints is built from the command's own group, so a scheduler manifest gets `blobhub scheduler diff -f <path>`.                                                                                                                                                                                                                                                                                            |
| `error-codes.md:53`          | `BLOB_NOT_WORKFLOW` means the blob is not a workflow blob.                                   | One shared resolver raises it for every group; the code name is kept as published for `--json` compatibility.                                                                                                                                                                                                                                                                                                               |
| `error-codes.md:56`          | `blob revisions` is "a future command" that "will let you switch" revisions.                 | It shipped, and it lists revisions with their phases rather than switching between them.                                                                                                                                                                                                                                                                                                                                    |
| `error-codes.md:56`          | The `REVISION_NOT_WRITABLE` message "lists the allowed phases".                              | The message names the phase and status it found; the allowed phases are a trailing comment on the hint.                                                                                                                                                                                                                                                                                                                     |
| `error-codes.md:86`          | `SANDBOX_NAME_SHADOWED`'s examples of pre-bound names include `json`.                        | `RESERVED_NAMES` (`compiler/sandbox.py:56`) unions the builtin, helper, typing and exception names and deliberately excludes `STDLIB_MODULES`, so `'json' in RESERVED_NAMES` is `False`. A top-level `json` never raises this code — it shadows the pre-bound module silently, which is the gap the [Sandbox](/cli/workflow/sandbox) reference documents. `Exit` replaces it in the example here, being genuinely reserved. |
| `error-codes.md:100`         | `EJECT_TARGET_EXISTS` can be answered by passing `--output <dir>` "to write somewhere else". | `--output` is refused with `MANIFEST_INVALID` on a component that already has a `code:` binding, so that remediation sends a reader into a second error.                                                                                                                                                                                                                                                                    |

## See also

* [Configuration](/cli/configuration) — the streams, envelopes and exit codes these codes travel on.
* [Concepts](/cli/concepts) — the platform behaviours behind several of them, including the `403` that cannot
  distinguish absent from inaccessible.
* [Utilities](/cli/utilities) — `doctor` reports several of these codes as rows rather than raising them.
