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, &params)
                            .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

  1. Switch the accelerator setting to CPU and retry — this isolates/dodges GPU backend and VRAM issues
  2. Use a smaller model (Small instead of Large/Turbo) if memory is the constraint
  3. Re-download the GGUF model in case the file is corrupt
  4. 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
  5. 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

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


AI-assisted analysis of cjpais/Handy@98a4d80cce (2026-08-16). Data as JSON: /api/errors/710a6880c392bed6. Report an issue: GitHub.