zeroclaw-labs/zeroclaw · warning

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

Error message

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

What it means

validate_audio() enforces a hard 25 MB (26,214,400 bytes) ceiling on audio before any network call, matching the upload cap of Whisper-compatible cloud APIs (MAX_AUDIO_BYTES in transcription.rs:14). Every cloud provider — Groq, OpenAI, Deepgram, AssemblyAI, and Google — calls validate_audio() at the top of its transcribe(), so oversized input is rejected locally and never uploaded. The size check runs before the extension/MIME check, so a huge file with a bad extension reports this error first.

Source

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

            WARN,
            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Reject)
                .with_outcome(::zeroclaw_log::EventOutcome::Failure)
                .with_attrs(::serde_json::json!({"extension": extension})),
            "transcription: unsupported audio format"
        );
        anyhow::Error::msg(format!(
            "Unsupported audio format '.{extension}'. \
             accepted: flac, mp3, mp4, mpeg, mpga, m4a, ogg, opus, wav, webm"
        ))
    })?;
    Ok((normalized_name, mime))
}

/// Validate audio data and resolve MIME type from file name.
/// Enforces the 25 MB cloud API cap. Returns `(normalized_filename, mime_type)` on success.
fn validate_audio(audio_data: &[u8], file_name: &str) -> Result<(String, &'static str)> {
    if audio_data.len() > MAX_AUDIO_BYTES {
        bail!(
            "Audio file too large ({} bytes, max {MAX_AUDIO_BYTES})",
            audio_data.len()
        );
    }
    resolve_audio_format(file_name)
}

// ── TranscriptionProvider trait ─────────────────────────────────

/// Trait for speech-to-text transcription_provider implementations.
#[async_trait]
pub trait TranscriptionProvider: Send + Sync + ::zeroclaw_api::attribution::Attributable {
    /// Human-readable transcription_provider name (e.g. "groq", "openai").
    fn name(&self) -> &str;

    /// Transcribe raw audio bytes. `file_name` includes the extension for
    /// format detection (e.g. "voice.ogg").
    async fn transcribe(&self, audio_data: &[u8], file_name: &str) -> Result<String>;

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Check the byte size at the channel edge before calling transcribe() and reply to the user (e.g. 'voice note too long to transcribe')
  2. Compress or split the audio with ffmpeg (downsample to 16 kHz mono Opus/FLAC) to get under 25 MB
  3. Set transcription.max_audio_bytes to a lower value so oversized input is rejected earlier by the manager with the 'global max' message instead
  4. Use local_whisper with its own max_audio_bytes if your self-hosted backend accepts larger payloads

Example fix

// before
let text = manager.transcribe(&audio, file_name).await?;

// after
const MAX_CLOUD: usize = 25 * 1024 * 1024;
if audio.len() > MAX_CLOUD {
    channel.reply("Voice note too long to transcribe (max 25 MB).").await;
    return Ok(());
}
let text = manager.transcribe(&audio, file_name).await?;
Defensive patterns

Strategy: validation

Validate before calling

const MAX_CLOUD_AUDIO: usize = 25 * 1024 * 1024; // keep in sync with MAX_AUDIO_BYTES

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

Try / catch

match manager.transcribe(&audio, name).await {
    Ok(text) => Some(text),
    Err(e) if e.to_string().contains("Audio file too large") => {
        channel.reply("Voice note exceeds the 25 MB transcription limit.").await;
        None
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling transcribe() (any cloud provider: groq, openai, deepgram, assemblyai, google) with audio_data.len() > 26214400 bytes. Typical case: a long Telegram voice note or an audio file sent as a document (Telegram allows up to 2 GB) routed into transcription.

Common situations: Music files or hour-long recordings forwarded as documents; channels that route every audio/* attachment to transcription; high-bitrate WAV exports (a 40-minute WAV easily exceeds 25 MB); a lower transcription.max_audio_bytes not set, so the 25 MB hard cap is the only limit hit.

Related errors


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