cjpais/Handy · error · anyhow::Error
transcribe-cpp transcription failed: {}
Error message
transcribe-cpp transcription failed: {} What it means
The transcribe-cpp (Whisper/GGUF) session's run() call failed during inference. The wrapped error comes from the GGML backend layer: compute failure on the selected backend (Vulkan/CUDA/Metal), out-of-memory loading activations for the chosen model, corrupted GGUF metadata, or a run-options mismatch against the loaded architecture. It is returned from transcribe() after the engine is safely returned to the slot, so the model stays loaded.
Source
Thrown at src-tauri/src/managers/transcription.rs:1326
};
debug!(
"transcribe-cpp run: task={:?}, language={:?}, initial_prompt={}",
run_options.task,
run_options.language,
run_options.family.is_some()
);
session
.run(&audio, &run_options)
.map(|t| {
// Whisper's audio-based LID (auto mode only;
// `None` when a language hint was passed).
model_detected_language = t.language;
t.text
})
.map_err(|e| {
anyhow::anyhow!("transcribe-cpp transcription failed: {}", e)
})
}
LoadedEngine::Parakeet(parakeet_engine) => {
let params = ParakeetParams {
timestamp_granularity: Some(TimestampGranularity::Segment),
..Default::default()
};
parakeet_engine
.transcribe_with(&audio, ¶ms)
.map(|r| r.text)
.map_err(|e| anyhow::anyhow!("Parakeet transcription failed: {}", e))
}
LoadedEngine::Moonshine(moonshine_engine) => moonshine_engine
.transcribe(&audio, &TranscribeOptions::default())
.map(|r| r.text)
.map_err(|e| anyhow::anyhow!("Moonshine transcription failed: {}", e)),
LoadedEngine::MoonshineStreaming(streaming_engine) => streaming_engine
.transcribe(&audio, &TranscribeOptions::default())View on GitHub (pinned to 98a4d80cce)
Solutions
- Switch the accelerator setting to CPU and retry — this isolates/dodges GPU backend and VRAM issues
- Use a smaller model (Small instead of Large/Turbo) if memory is the constraint
- Re-download the GGUF model in case the file is corrupt
- Update GPU drivers; on Linux run with VK_LOADER_DEBUG=error to surface Vulkan loader faults, or try --list-devices to verify the device registry
- Update Handy — arch/run-options mismatches (e.g. #1601 voxtral rejections) are fixed over time
Example fix
// before
session.run(&audio, &run_options).map_err(|e| anyhow::anyhow!("transcribe-cpp transcription failed: {}", e))?;
// after — validate input first, and retry on CPU when a GPU backend fails
anyhow::ensure!(audio.iter().all(|s| s.is_finite()), "audio contains NaN/inf samples");
let text = match session.run(&audio, &run_options) {
Ok(t) => t,
Err(e) if backend_is_gpu(session.backend()) => {
warn!("GPU inference failed ({}), retrying on CPU", e);
reload_model_on_cpu_and_retry(&audio, &run_options)?
}
Err(e) => return Err(anyhow::anyhow!("transcribe-cpp transcription failed: {}", e)),
}; Defensive patterns
Strategy: try-catch
Validate before calling
// Validate audio before inference and confirm the backend is sane anyhow::ensure!(!audio.is_empty(), "empty audio"); anyhow::ensure!(audio.iter().all(|s| s.is_finite()), "audio has NaN/inf samples"); // Optionally check backend registered: transcribe_cpp::backend_available(Backend::Vulkan)
Try / catch
match tm.transcribe(audio.clone()) {
Err(e) if e.to_string().contains("transcribe-cpp transcription failed") => {
// GPU/OOM flake: switch accelerator to CPU once and retry
set_accelerator_setting(TranscribeAcceleratorSetting::Cpu);
tm.reload_model();
tm.transcribe(audio)
}
other => other,
} Prevention
- Choose model sizes that fit comfortably in VRAM (leave headroom for other GPU apps)
- Keep GPU drivers updated; on Linux verify Vulkan with --list-devices and VK_LOADER_DEBUG=error
- Re-download GGUF models after interrupted downloads instead of retrying loads on partial files
- Update Handy when new architectures are added — run-option mismatches get gated over time
When it happens
Trigger: session.run(&audio, &run_options) errors for the LoadedEngine::TranscribeCpp arm: GPU backend failure (device lost, driver crash, Vulkan surface issues), VRAM/RAM exhaustion with large GGUF models, truncated/corrupt GGUF file, or run options (translate / initial prompt extension) rejected by the loaded non-whisper arch despite capability gating.
Common situations: Selecting a large Whisper model on a GPU with insufficient VRAM; outdated or crashing GPU drivers (especially Vulkan on Linux); model file corrupted after a partial download; running under emulation (Windows x64 on ARM64) where GPU is force-disabled; very long audio clips spiking memory.
Related errors
- Failed to create session for whisper model {}: {}
- No compute device with index {index} (see --list-devices)
- Device index {index} has kind '{other}', which cannot host a
- Failed to load whisper model {}: {}
- Parakeet transcription failed: {}
AI-assisted analysis of cjpais/Handy@98a4d80cce (2026-08-16).
Data as JSON: /api/errors/710a6880c392bed6.
Report an issue: GitHub.