Zackriya-Solutions/meetily · error · anyhow::Error

Whisper transcription failed on segment {}: {}

Error message

Whisper transcription failed on segment {}: {}

What it means

WhisperEngine::transcribe_audio_with_confidence(samples, language) returned Err for segment i. The inner '{}' comes from whisper-rs/whisper.cpp: common causes are no model currently loaded on the engine, an unsupported language code, an invalid audio buffer, or out-of-memory loading context state for a long segment.

Source

Thrown at frontend/src-tauri/src/audio/retranscription.rs:383

        if segment.samples.len() < 1600 {
            debug!("Skipping short segment {} with {} samples", i, segment.samples.len());
            continue;
        }

        // Transcribe this segment
        let (text, conf) = if use_parakeet {
            let engine = parakeet_engine.as_ref().unwrap();
            let text = engine
                .transcribe_audio(segment.samples.clone())
                .await
                .map_err(|e| anyhow!("Parakeet transcription failed on segment {}: {}", i, e))?;
            (text, 0.9f32)
        } else {
            let engine = whisper_engine.as_ref().unwrap();
            let (text, conf, _) = engine
                .transcribe_audio_with_confidence(segment.samples.clone(), language.clone())
                .await
                .map_err(|e| anyhow!("Whisper transcription failed on segment {}: {}", i, e))?;
            (text, conf)
        };

        // Skip empty transcripts
        let trimmed = text.trim();
        if !trimmed.is_empty() {
            debug!(
                "Segment {}/{}: {:.1}s, conf={:.2}, text='{}'",
                i + 1, processable_count, segment_duration_sec, conf,
                if trimmed.len() > 80 { let mut end = 80; while !trimmed.is_char_boundary(end) { end -= 1; } &trimmed[..end] } else { trimmed }
            );
            all_transcripts.push((text, segment.start_timestamp_ms, segment.end_timestamp_ms));
            total_confidence += conf;
        } else {
            debug!("Segment {}/{}: {:.1}s — empty transcription", i + 1, processable_count, segment_duration_sec);
        }
    }

View on GitHub (pinned to 0281737d87)

Solutions

  1. Read the inner error: if it mentions the language, pass a valid ISO-639-1 code or None for auto-detect.
  2. Confirm the earlier 'Whisper model ... loaded successfully' log line appears - if not, the engine lost its model.
  3. Switch to a smaller model (base/small) or free memory and retry.
  4. If only one segment of many fails, a retry usually succeeds - transient state, not bad audio.
Defensive patterns

Strategy: retry

Validate before calling

// Validate language codes before passing them to whisper
fn is_valid_whisper_language(lang: &Option<String>) -> bool {
    match lang {
        None => true,
        Some(l) => l.len() == 2 && l.chars().all(|c| c.is_ascii_alphabetic()),
    }
}

Try / catch

// Retry transient inference errors once; fail fast on language errors
match engine.transcribe_audio_with_confidence(samples, language.clone()).await {
    Ok(v) => v,
    Err(e) if e.to_string().contains("language") => return Err(anyhow!("invalid language {language:?}: {e}")),
    Err(e) => { /* one retry, then propagate with segment index */ }
}

Prevention

When it happens

Trigger: Retranscribing with a language value whisper-rs rejects (not a valid ISO-639-1 code it supports); the Whisper model being unloaded mid-loop by another code path; a segment that still exceeds usable context after splitting; memory pressure with large-v3.

Common situations: User picks an explicit language in the retranscribe dialog that whisper rejects; running large models on machines with low VRAM/RAM; concurrent engine access from import or live pipeline.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16). Data as JSON: /api/errors/69903a82db9b0dfd. Report an issue: GitHub.