SubtitleEdit/subtitleedit · error · InvalidOperationException
F5-TTS (CrispASR) requires a reference voice WAV. Import one
Error message
F5-TTS (CrispASR) requires a reference voice WAV. Import one via the voice settings, then pick it in the voice combo. Reference WAV should be 24 kHz mono (3-10 s of clean speech) with an adjacent .txt file holding the spoken transcription.
What it means
InvalidOperationException from F5TtsCrispAsr.Speak: the F5TtsVoice was accepted (type matched) but its FilePath is null/empty. F5-TTS is a voice-cloning engine — it always needs a reference WAV (24 kHz mono, 3–10 s clean speech) plus an adjacent .txt transcription sidecar. Unlike CosyVoice3, this is a hard throw rather than an error result.
Source
Thrown at src/ui/Features/Video/TextToSpeech/Engines/F5TtsCrispAsr.cs:368
GetVoices(language);
public async Task<TtsResult> Speak(
string text,
string outputFolder,
Voice voice,
TtsLanguage? language,
string? region,
string? model,
CancellationToken cancellationToken)
{
if (voice.EngineVoice is not F5TtsVoice f5Voice)
{
throw new ArgumentException("Voice is not an F5TtsVoice");
}
if (string.IsNullOrEmpty(f5Voice.FilePath))
{
throw new InvalidOperationException(
"F5-TTS (CrispASR) requires a reference voice WAV. "
+ "Import one via the voice settings, then pick it in the voice combo. "
+ "Reference WAV should be 24 kHz mono (3-10 s of clean speech) with an "
+ "adjacent .txt file holding the spoken transcription.");
}
var refText = TryReadRefText(f5Voice.FilePath);
var modelKey = ResolveModelKey(model);
await EnsureServerRunningAsync(modelKey, f5Voice.FilePath, refText, cancellationToken);
var outputFileName = Path.Combine(TtsOutputFolder.Resolve(outputFolder, GetSetFolder), Guid.NewGuid() + ".wav");
var speed = Math.Clamp(Se.Settings.Video.TextToSpeech.F5TtsCrispAsrSpeed, 0.25, 4.0);
// Deliberately NO `voice` / `ref_text` field: the server rejects absolute paths outright
// (HTTP 400, "'voice' must not contain … path separators" — path-traversal guard), so
// sending f5Voice.FilePath failed every synthesis. The f5-tts backend reads the reference
// from the startup --voice / --ref-text flags (no bare-name resolution), and the server
// restarts on (voice, ref-text) change — see EnsureServerRunningAsync. Same bug family asView on GitHub (pinned to 17a9f07487)
Solutions
- Import a 24 kHz mono reference WAV (3–10 s clean speech) via the F5-TTS voice settings, then select it in the voice combo.
- Place an adjacent .txt file with the spoken transcription next to the WAV so ref-text is auto-read.
- Validate FilePath is set before queueing the segment so the run aborts earlier with a clearer message.
Example fix
// before
var f5Voice = new F5TtsVoice { Name = "my clone" }; // no FilePath
await f5TtsEngine.Speak(text, out, new Voice(f5Voice), lang, region, model, ct);
// after
var f5Voice = new F5TtsVoice { Name = "my clone", FilePath = @"C:\voices\ref.wav" };
await f5TtsEngine.Speak(text, out, new Voice(f5Voice), lang, region, model, ct); Defensive patterns
Strategy: validation
Validate before calling
if (voice.EngineVoice is F5TtsVoice f5 && string.IsNullOrEmpty(f5.FilePath)) {
Se.WriteToolsLog("F5-TTS voice has no reference WAV; prompt the user to import one.", true);
return new TtsResult { Text = text, FileName = string.Empty, Error = true, ErrorMessage = "Import a 24 kHz mono reference WAV first." };
} Try / catch
try { await f5TtsEngine.Speak(text, out, voice, lang, region, model, ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("requires a reference voice WAV", StringComparison.Ordinal))
{ Se.WriteToolsLog("Import a 24 kHz mono reference WAV for this F5-TTS voice, then retry.", true); } Prevention
- Validate F5TtsVoice.FilePath is set before queueing segments.
- Always pair the WAV with an adjacent .txt transcription sidecar.
- Use 24 kHz mono, 3–10 s clean speech for the reference.
When it happens
Trigger: Speak proceeds past the type check, then string.IsNullOrEmpty(f5Voice.FilePath) is true; the voice was created without importing a reference WAV, or the FilePath was cleared.
Common situations: An F5TtsVoice constructed without an import; the imported WAV file path was reset/lost on settings reload; a cast row selected a default F5 voice that has no reference attached.
Related errors
- Voice is not an F5TtsVoice
- F5-TTS (CrispASR) — the crispasr server crashed during synth
- F5-TTS (CrispASR) request failed — the connection to the cri
- F5-TTS (CrispASR) synthesis failed ({(int)response.StatusCod
- CrispASR executable not found. Install CrispASR via Video →
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/2fa21c0bb0e27025.
Report an issue: GitHub.