zeroclaw-labs/zeroclaw · warning

Audio file too large ({} bytes, local_whisper max {})

Error message

Audio file too large ({} bytes, local_whisper max {})

What it means

LocalWhisperProvider enforces its own configurable max_audio_bytes (from [transcription.local_whisper]) at the top of transcribe(), before POSTing to the self-hosted Whisper-compatible server. This is independent of the 25 MB cloud cap (error 282) and of the manager-wide transcription.max_audio_bytes (error 299) — it applies only when the local_whisper provider is selected.

Source

Thrown at crates/zeroclaw-channels/src/transcription.rs:847

        let bridge = zeroclaw_config::schema::LocalWhisperConfig {
            url: cfg.uri.clone(),
            bearer_token: cfg.bearer_token.clone(),
            max_audio_bytes: cfg.max_audio_bytes,
            timeout_secs: cfg.timeout_secs,
        };
        Self::from_config(alias, &bridge)
    }
}

#[async_trait]
impl TranscriptionProvider for LocalWhisperProvider {
    fn name(&self) -> &str {
        "local_whisper"
    }

    async fn transcribe(&self, audio_data: &[u8], file_name: &str) -> Result<String> {
        if audio_data.len() > self.max_audio_bytes {
            bail!(
                "Audio file too large ({} bytes, local_whisper max {})",
                audio_data.len(),
                self.max_audio_bytes
            );
        }

        let (normalized_name, mime) = resolve_audio_format(file_name)?;

        let client =
            zeroclaw_config::schema::build_runtime_proxy_client("transcription.local_whisper");

        // to_vec() clones the buffer for the multipart payload; peak memory per
        // call is ~2× max_audio_bytes. TODO: replace with streaming upload once
        // reqwest supports body streaming in multipart parts.
        let file_part = Part::bytes(audio_data.to_vec())
            .file_name(normalized_name)
            .mime_str(mime)?;

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Raise [transcription.local_whisper].max_audio_bytes if your self-hosted backend can handle the payload
  2. Otherwise reject or compress oversized audio at the channel layer before transcribing
  3. Keep the three limits straight: transcription.max_audio_bytes (manager-wide), local_whisper.max_audio_bytes (this provider), and the hardcoded 25 MB cloud cap

Example fix

# before
[transcription.local_whisper]
api_url = "http://localhost:9000/v1/audio/transcriptions"
max_audio_bytes = 10485760

# after
[transcription.local_whisper]
api_url = "http://localhost:9000/v1/audio/transcriptions"
max_audio_bytes = 52428800
Defensive patterns

Strategy: validation

Validate before calling

// Mirror your [transcription.local_whisper].max_audio_bytes at the call site
const LOCAL_WHISPER_MAX: usize = 10 * 1024 * 1024;

fn within_local_whisper_cap(audio: &[u8]) -> bool {
    audio.len() <= LOCAL_WHISPER_MAX
}

Try / catch

match manager.transcribe(&audio, name).await {
    Ok(text) => Some(text),
    Err(e) if e.to_string().contains("local_whisper max") => {
        channel.reply("Voice note exceeds the local transcription limit.").await;
        None
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: transcribe_with_provider(..., "local_whisper") (or an agent bound to local_whisper) with audio_data.len() exceeding the configured local_whisper.max_audio_bytes.

Common situations: A local cap set lower than expected (e.g. 10 MB default-style value) while users send 15 MB voice notes; raising transcription.max_audio_bytes but forgetting the per-provider local_whisper.max_audio_bytes key; long WAV files that would pass a compressed-format limit.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/7231ee6d29afb00c. Report an issue: GitHub.