SubtitleEdit/subtitleedit · error · InvalidOperationException
Chatterbox TTS could not use the reference voice "{Path.GetF
Error message
Chatterbox TTS could not use the reference voice "{Path.GetFileName(chatterboxVoice.FilePath)}" for cloning: CrispASR needs a {CloneReferenceSampleRate / 1000} kHz mono WAV and re-encoding this one did not produce that. Re-import the voice, or convert it yourself with `ffmpeg -i <input> -ar {CloneReferenceSampleRate} -ac 1 -c:a pcm_s16le <output>.wav`. Chatterbox TTS synthesis failed ({(int)response.StatusCode}): {errorBody} What it means
HTTP non-success from /v1/audio/speech AND LooksLikeCloneReferenceRejected(serverLog) matched. The reference voice WAV must be {CloneReferenceSampleRate/1000} kHz mono; the engine's ffmpeg re-encode did not produce that, so CrispASR rejected the clone. The message embeds the exact ffmpeg command to convert manually.
Source
Thrown at src/ui/Features/Video/TextToSpeech/Engines/ChatterboxTtsCpp.cs:436
var serverLog = SnapshotServerLog();
var launchCommand = _serverLaunchCommand;
var errMsg = $"Chatterbox TTS server error {(int)response.StatusCode} {response.StatusCode} - "
+ $"Voice: {chatterboxVoice}, Text: {text}, RequestJson: {body}, "
+ $"ResponseBody: {errorBody}, ServerLog: {serverLog}"
+ LaunchCmdSuffix(launchCommand);
Se.LogError(errMsg);
Se.WriteToolsLog(errMsg);
// The HTTP body only ever says "backend returned empty audio" - the reason the
// backend produced none is in the server log, so name it (#13508).
var prefix = LooksLikeCloneReferenceRejected(serverLog)
? $"Chatterbox TTS could not use the reference voice \"{Path.GetFileName(chatterboxVoice.FilePath)}\" for cloning: "
+ $"CrispASR needs a {CloneReferenceSampleRate / 1000} kHz mono WAV and re-encoding this one did not produce that. "
+ "Re-import the voice, or convert it yourself with "
+ $"`ffmpeg -i <input> -ar {CloneReferenceSampleRate} -ac 1 -c:a pcm_s16le <output>.wav`. "
: string.Empty;
throw new InvalidOperationException(
prefix
+ $"Chatterbox TTS synthesis failed ({(int)response.StatusCode}): {errorBody}"
+ (string.IsNullOrEmpty(serverLog) ? string.Empty : $"{Environment.NewLine}Server log:{Environment.NewLine}{serverLog}")
+ LaunchCmdSuffix(launchCommand));
}
await using var fileStream = File.Create(outputFileName);
await using var contentStream = await response.Content.ReadAsStreamAsync(cancellationToken);
await contentStream.CopyToAsync(fileStream, cancellationToken);
}
return new TtsResult(outputFileName, text);
}
/// <summary>
/// Builds the <c>/v1/audio/speech</c> JSON payload. Extracted so the cloning attestations are
/// unit-testable without a running crispasr server.
/// </summary>View on GitHub (pinned to 17a9f07487)
Solutions
- Re-import the voice from a clean source.
- Convert manually: `ffmpeg -i <input> -ar <CloneReferenceSampleRate> -ac 1 -c:a pcm_s16le <output>.wav` (rate shown in the message).
- Ensure ffmpeg is installed/on PATH so the automatic re-encode step runs.
- Confirm the reference is a real PCM WAV, not a renamed lossy file.
Example fix
// before: import any audio as a clone reference // after: pre-convert at import time ffmpeg -i voice.mp3 -ar 16000 -ac 1 -c:a pcm_s16le voice_ref.wav
Defensive patterns
Strategy: validation
Validate before calling
var refPath = chatterboxVoice.FilePath;
if (!IsPcmMonoWavAtRate(refPath, CloneReferenceSampleRate))
return Invalid("reference must be " + CloneReferenceSampleRate + " Hz mono PCM WAV"); Try / catch
try { await chatterbox.Speak(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("could not use the reference voice"))
{ /* re-encode with the ffmpeg command in the message, then re-import */ } Prevention
- Pre-convert clone references to the required sample rate / mono PCM WAV at import time.
- Ensure ffmpeg is on PATH so the automatic re-encode runs.
- Reject non-PCM or stereo files at import rather than at synthesis.
When it happens
Trigger: chatterboxVoice.FilePath is a WAV of wrong sample rate, channel count, or codec; the auto re-encode (EnsureCloneReferenceIsUsable) failed to produce the required format; ffmpeg missing so re-encode never ran; backend returns non-2xx with a 'backend returned empty audio' style body and the server log shows the reference was rejected.
Common situations: Re-imported a stereo or 48 kHz WAV as a Chatterbox clone reference; ffmpeg not on PATH; reference WAV truncated; user imported an mp3 renamed to .wav.
Related errors
- Chatterbox TTS hit a CrispASR runtime bug during synthesis (
- Chatterbox TTS request failed — the crispasr server crashed
- Chatterbox TTS request failed — the connection to the crispa
- Chatterbox TTS synthesis failed ({(int)response.StatusCode})
- CrispASR executable not found. Install CrispASR via Video →
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/c0b889c9b85fa531.
Report an issue: GitHub.