Every user-facing failure prints a stable code on stderr:
error [E_MODEL_MISSING]: voice 'ru-vosk-m02' not installed. run: kesha install --tts
The code is stable across releases — quote it in bug reports. Engine codes are
introspectable via kesha-engine --error-codes-json. Codes are recorded
(leak-free) in Stats and diagnostic logs; the human
message may contain a path and is sanitized before storage, but the code never
needs sanitizing.
| Code | Category | Retryable | When it fires | How to fix |
|---|---|---|---|---|
E_INPUT_NOT_FOUND |
input | no | The input audio path doesn't exist (or no stdin was piped). | Check the path; pass a readable file. |
E_BAD_AUDIO |
input | no | The audio container/codec couldn't be decoded (or the file couldn't be opened for a reason other than "missing"). | Re-export to wav/ogg/mp3; verify the file isn't truncated; check permissions. |
E_MODEL_MISSING |
model | no | A required model or voice isn't installed. | kesha install / kesha install --tts. |
E_MODEL_DOWNLOAD |
model | yes | A model download failed (network or mirror error). | Retry; check connectivity and KESHA_MODEL_MIRROR. |
E_CACHE_CORRUPT |
model | no | A cached model file failed SHA-256 verification. | kesha install --no-cache to re-fetch. |
E_MODEL_LOAD |
model | no | A model file exists but failed to load. | Reinstall the model; check disk space. |
E_UNSUPPORTED_PLATFORM |
platform | no | The feature isn't supported on this OS/arch (e.g. microphone recording off macOS). | Use a supported platform (see the README platform matrix). |
E_SIDECAR_MISSING |
platform | no | A helper sidecar is missing or exited nonzero (e.g. say-avspeech). |
Reinstall; ensure the sidecar sits beside the engine (macOS). |
E_NO_BACKEND |
platform | no | The binary was built without an ASR backend. | Use an official release build. |
E_TEXT_EMPTY |
tts | no | Synthesis text was empty. | Pass non-empty text. |
E_TEXT_TOO_LONG |
tts | no | Text exceeded the maximum length. | Split into shorter requests. |
E_VOICE_UNKNOWN |
tts | no | The voice id wasn't recognized. | kesha say --list-voices. |
E_SSML_INVALID |
tts | no | SSML was malformed (missing <speak> root, DOCTYPE, or unsupported relative rate). |
Fix the SSML; see docs/tts.md. |
E_SSML_UNSUPPORTED |
tts | no | SSML isn't supported for this engine/voice. | Use a plain-text request or a supported voice. |
E_SCRIPT_UNSUPPORTED |
tts | no | The text uses a script the chosen voice's G2P can't phonemize (e.g. Devanagari / kana-kanji / Han for the FluidAudio Kokoro hi/ja/zh voices, which only handle Latin input). |
Romanize the text (transliterate to Latin), or use a voice whose engine supports the script. See #492. |
E_TRANSCRIBE_FAILED |
transcribe | no | The ASR pipeline failed. | Re-run; file a bug with a support bundle. |
E_DIARIZE_TIMEOUT |
transcribe | yes | Speaker diarization timed out (cold compile or long audio). | Re-run once warm; shorten the audio. |
E_ENGINE_SPAWN |
internal | no | The CLI couldn't spawn the engine subprocess. | kesha install; check the engine binary path (KESHA_ENGINE_BIN). |
E_INVALID_ARG |
input | no | A CLI flag or argument was invalid. | See kesha --help. |
E_INTERNAL |
internal | no | An unexpected or uncoded failure. | File a bug with kesha support-bundle. |
- Engine codes (everything except
E_ENGINE_SPAWN) are defined in the Rust engine and emitted on its stderr aserror [CODE]: …. List them withkesha-engine --error-codes-json. E_ENGINE_SPAWNoriginates only in the TypeScript CLI, for the failure to spawn the engine subprocess at all.E_INVALID_ARGandE_INPUT_NOT_FOUNDare emitted by both the engine and the TypeScript CLI: the CLI validates arguments and checks input existence up front, and the engine emits the same codes when a bad argument or a missing file reaches it directly (e.g.kesha-engine saywith conflicting--model/--voice-file, or a malformed--format).
Codes are part of the public contract. A code's meaning will not change; new codes may be added. The human-readable message after the code is not contractual and may be reworded — match on the code, not the message.
In addition to the stable error [CODE] line above, the process exits with a
status that lets scripts branch without parsing stderr:
| Exit code | Meaning |
|---|---|
0 |
Success. |
1 |
Operational error — engine/model not installed, a download or install failed, an unknown command, or no input was given. |
2 |
Invalid arguments or usage (mutually-exclusive flags, a bad --format, empty say text, …). |
4 |
Unexpected/uncoded internal failure. |
5 |
kesha say text exceeds the length limit. |
kesha say and other engine-backed commands may also exit with the engine's
own non-zero status when the engine itself fails. For fine-grained handling,
match on the stable error [CODE] line — it is the reliable signal; the numeric
exit status only distinguishes the broad categories above.