# When the CLI aborts

The most common aborts of the CLI, in the order in which they occur: with the message you see, the exit code, its meaning, and the way back. Each solution points to the page that covers the topic.

> **Type:** troubleshooting
> **For:** Anyone who has issued a command and sees a message with `✗` or `{"error": …}` instead of a result
> **Prerequisite:** the exit code of the call (`echo $?` right after the command), and a call through `node …/dist/main.js` or `szenera`, not through `pnpm run`

| Symptom | Meaning | Solution |
|---|---|---|
| `Unbekannter Befehl „device lister".` (unknown command) and below it the whole overview (exit 1) | The words match no command in the registry: a typo, the wrong order (`list device`), or a flag without `=` that was read as a word. | Choose the command from the overview. Flags carry their value after the equals sign (`--limit=20`). See [Commands for your organization](/cli/commands-organization). |
| `„device list" kennt die Flagge „--state" nicht. Bekannt sind: …` (unknown flag) (exit 1) | An unknown flag is an error, not a silent hint. The message lists the valid ones. | Use one of the flags the message names. `szenera <befehl> --help` explains them. |
| `„--limit" braucht einen Wert: --limit=<anzahl>.` (flag needs a value) (exit 1) | The flag was given without an equals sign. `--limit 20` does not exist. | Write `--limit=20`. |
| `„device get" braucht <id> — …` (positional argument missing) (exit 1) | A required positional argument is missing. | Append the ID as `--help` shows it. |
| `„scn_01K…" ist keine Kennung für ein Medium: erwartet wird ast_…` (not an ID for a media item) (exit 1) | The prefix of the ID does not match the command. No call went out. | Use the right ID: `ast_` media item, `scn_` scene, `pll_` playlist, `sch_` program, `ply_` display, `dev_` device. |
| `… wandert in den Papierkorb. Wenn das gewollt ist: --yes anhängen.` (moves to the trash, append `--yes` if intended) (exit 1) | An irreversible action without consent in the call. | Append `--yes` if the consequence is intended. |
| `Keine Konfiguration gefunden — die Kommandozeile weiß nicht, mit welcher Umgebung sie sprechen soll.` (no configuration found) (exit 2) | Neither a file at one of the two locations nor `SZENERA_BASE_URL`. | Create a profile or set `SZENERA_BASE_URL` and `SZENERA_API_KEY`. See [Profiles and credentials](/cli/profiles-and-credentials). |
| `Unbekanntes Profil „staging". … führt: dev, prod.` (unknown profile) (exit 2) | `--profile=` or `SZENERA_PROFILE` names a profile the file does not hold. | Choose one of the names listed. |
| `„asset delete" ist im Profil „prod" gesperrt — das Profil ist schreibgeschützt.` (blocked, the profile is write-protected) (exit 2) | A command that changes something meets a write-protected profile, or one without the setting, in which case `true` applies. | If the profile may write: set `readOnly: false`. See [Profiles and credentials](/cli/profiles-and-credentials). |
| `Kein API-Schlüssel: erwartet wird ein Wert mit dem Präfix 'ak_' oder 'opk_' …` (not an API key) (exit 2) | The value in the profile or in `SZENERA_API_KEY` is not a key: truncated, swapped, empty. | Take the plaintext from the portal. See [Profiles and credentials](/cli/profiles-and-credentials). |
| `„whoami" braucht einen Ausweis, das Profil „…" trägt keinen.` (needs a credential, the profile has none) (exit 1) | The profile has `credential: {"kind": "none"}` or none at all. Only `health` and `health public` run that way. | Add `SZENERA_API_KEY=ak_…` or set `credential` in the profile. |
| HTTP 401 (exit 3) despite a key that is set | The key is not valid: revoked, expired, or the profile points to a different environment than the one the key was issued for. | Check each profile with `szenera whoami --profile=<name>` and create a new key. See [Profiles and credentials](/cli/profiles-and-credentials). |
| HTTP 403 `Permission.Denied` (exit 4) | The credential is valid but the permission is missing, or the route requires a permission that a key may not carry (such as `identity.device.list`). | Check the “Key” column of the command pages. Extend the key’s permissions or use a profile with password sign-in. |
| `Die Anfrage an „composition.scenes.update" entspricht nicht dem Vertrag:` (the request does not match the contract) with field paths (exit 1) | Your input, usually a file behind `--document` or `--entries`, does not conform to the schema. No network packet went out. | Correct the fields named in the file. See [JSON output and exit codes](/cli/output-and-exit-codes). |
| `Die Antwort auf „…" widerspricht dem Vertrag, den diese CLI (0.1.0) kennt.` (the response contradicts the contract) (exit 9) | Version skew: the other end is older or newer than the CLI, and not broken. | Append `--raw`. The raw response on standard output shows which field is missing. Build the CLI from the matching version. See [JSON output and exit codes](/cli/output-and-exit-codes). |
| HTTP 409 (exit 6) on `scene update`, `playlist update`, `role update` | The expected version no longer matches: someone changed it in between. | Call again without `--version` (the command then reads the version itself). `scene update --retry` retries once on its own. |
| HTTP 422 (exit 7) with `Scene.PublishValidationFailed` | The live check of the document failed: a media item is gone, a template was deleted. | Fix the cause. Findings cannot be skipped here. |
| HTTP 429 (exit 8) | Too many calls. `retryAfterSeconds` is in the error. | Wait that long, then retry. See [Scripts and CI](/cli/scripts-and-ci). |
| `Network.RequestFailed`, `fetch failed` (exit 10) | No HTTP response at all: wrong address, no network, no name resolution. | Check `SZENERA_BASE_URL` or `services` in the profile. `szenera health` needs no credential and separates network from sign-in. |
| `health` ends with exit 9 | The environment reports that it is not ready: HTTP 503 on `GET /health/ready`. | Wait and check again. The table names the check that is red. |
| Exit 11 after `asset upload`, `device get-command --wait` | The operation went through and ended in failure: processing failed, command `failed`. | Read the finding in the error. `asset reprocess` is the way back for a media item in the state `error`. See [Scripts and CI](/cli/scripts-and-ci). |
| Exit 12 `Zeitlimit … erreicht — der Ausgang ist unbekannt.` (time limit reached, outcome unknown) | The time limit took effect. The operation may still be running. | Do not retry blindly. First check with `asset get` or `device get-command`, then run again with a larger `--timeout`. See [Scripts and CI](/cli/scripts-and-ci). |
| `„abc" ist keine Dauer. Erlaubt sind 500ms, 90s, 20m, 2h — oder eine Zahl in Sekunden.` (not a duration) (exit 1) | `--timeout` or `--interval` uses a format the CLI does not recognize. | Use one of the formats named. |
| `„--limit=500" liegt außerhalb von 1…200.` (out of range) (exit 1) | The contract allows no more per page. | Use `--limit=200` and `--all`. See [Scripts and CI](/cli/scripts-and-ci). |
| `Der Rumpf ist kein gültiges JSON` (the body is not valid JSON) on `api post` (exit 1) | The shell changed the body: quotes, dollar signs, line breaks. | Pass larger bodies as a file: `@rumpf.json`. |
| Every error ends with exit 1, whatever happens | The call runs through `pnpm run`, which swallows the codes. | Call `node packages/cli/dist/main.js …` directly. See [JSON output and exit codes](/cli/output-and-exit-codes). |
| The output is a table although a script reads it, or JSON in the terminal | The format follows standard output: terminal means table, pipe means JSON. `SZENERA_OUTPUT` can override that. | Force `--json` or `--table`. |
| The command ends with exit 0, but `ergebnis.json` does not contain `.daten` | There is no envelope: standard output carries the payload directly. | Read `.items[]` instead of `.daten.items[]`. See [JSON output and exit codes](/cli/output-and-exit-codes). |

## Related

- [Profiles and credentials](/cli/profiles-and-credentials)
- [JSON output and exit codes](/cli/output-and-exit-codes)
- [Scripts and CI](/cli/scripts-and-ci)
