Environment
whisper.cpp version: 1.9.2 (Homebrew bottle, arm64_tahoe)
OS: macOS 26.6.2 (build 25G83)
Architecture: arm64 (Apple Silicon, Metal-accelerated build)
Invocation: whisper-cli -m ggml-small.en.bin -f audio -oj -of output -np
Summary
When whisper-cli fails to decode an input audio file, it prints an error to stderr and correctly produces no output file — but still exits with status code 0. A caller that checks the exit code to decide whether the run succeeded (the documented/expected way to detect failure from a CLI) will incorrectly treat this as success, and then fail later and confusingly when it tries to read an output file that was never written.
Steps to reproduce
Obtain an audio file that whisper.cpp's built-in miniaudio-based decoder can't read. In my case this was a podcast episode encoded as AAC inside an M4A/MP4 container (ffprobe reports: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 262 kb/s) — a plain standalone MP3 from the same general pipeline decodes and transcribes fine, so this appears to be specific to this container/codec combination rather than a general miniaudio failure.
Run:
whisper-cli -m ggml-small.en.bin -f the-file -oj -of output -np
echo "exit code: $?"
Observe stderr output:
read_audio_data: reading audio data from '...' ...
read_audio_data: trying to decode with miniaudio
read_audio_data: failed to read audio data
error: failed to read audio file '...'
Observe the process exits with exit code: 0, and no output.json (or .txt/etc.) is created.
Expected behavior
A failed decode should produce a non-zero exit code, so scripts/wrappers driving whisper-cli can reliably detect the failure from the exit status alone, consistent with normal CLI conventions.
Actual behavior
Exit code is 0 despite the file never being processed and no output ever being written.
Notes
I don't believe this is the same issue as #3501 (an ASan invalid-free inside read_audio_data) — no crash or sanitizer involved here, just a silently-swallowed failure with a misleading exit code.
PR #3387 ("clearer errors for unsupported extensions and failed audio decode") is adjacent — it improves the message printed on a failed decode — but as far as I can tell doesn't touch the exit code, so this would still reproduce even with that PR merged.
Worked around this on my end by transcoding every input through ffmpeg to 16kHz mono WAV before handing it to whisper-cli, and by independently verifying the expected output file actually exists afterward rather than trusting the exit code — but it'd be good for whisper-cli to report its own failures correctly so callers don't need that second check.
Suggested fix
Have the CLI's main() return a non-zero status (or the relevant caller check read_audio_data's return value and propagate a failure) whenever no file was successfully transcribed, rather than only reflecting fatal/crash-level errors in the exit code.
Environment
whisper.cpp version: 1.9.2 (Homebrew bottle, arm64_tahoe)
OS: macOS 26.6.2 (build 25G83)
Architecture: arm64 (Apple Silicon, Metal-accelerated build)
Invocation: whisper-cli -m ggml-small.en.bin -f audio -oj -of output -np
Summary
When whisper-cli fails to decode an input audio file, it prints an error to stderr and correctly produces no output file — but still exits with status code 0. A caller that checks the exit code to decide whether the run succeeded (the documented/expected way to detect failure from a CLI) will incorrectly treat this as success, and then fail later and confusingly when it tries to read an output file that was never written.
Steps to reproduce
Obtain an audio file that whisper.cpp's built-in miniaudio-based decoder can't read. In my case this was a podcast episode encoded as AAC inside an M4A/MP4 container (ffprobe reports: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 262 kb/s) — a plain standalone MP3 from the same general pipeline decodes and transcribes fine, so this appears to be specific to this container/codec combination rather than a general miniaudio failure.
Run:
Observe stderr output:
Observe the process exits with
exit code: 0, and no output.json (or .txt/etc.) is created.Expected behavior
A failed decode should produce a non-zero exit code, so scripts/wrappers driving whisper-cli can reliably detect the failure from the exit status alone, consistent with normal CLI conventions.
Actual behavior
Exit code is 0 despite the file never being processed and no output ever being written.
Notes
I don't believe this is the same issue as #3501 (an ASan invalid-free inside read_audio_data) — no crash or sanitizer involved here, just a silently-swallowed failure with a misleading exit code.
PR #3387 ("clearer errors for unsupported extensions and failed audio decode") is adjacent — it improves the message printed on a failed decode — but as far as I can tell doesn't touch the exit code, so this would still reproduce even with that PR merged.
Worked around this on my end by transcoding every input through ffmpeg to 16kHz mono WAV before handing it to whisper-cli, and by independently verifying the expected output file actually exists afterward rather than trusting the exit code — but it'd be good for whisper-cli to report its own failures correctly so callers don't need that second check.
Suggested fix
Have the CLI's main() return a non-zero status (or the relevant caller check read_audio_data's return value and propagate a failure) whenever no file was successfully transcribed, rather than only reflecting fatal/crash-level errors in the exit code.