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
- Check the byte size at the channel edge before calling transcribe() and reply to the user (e.g. 'voice note too long to transcribe')
- Compress or split the audio with ffmpeg (downsample to 16 kHz mono Opus/FLAC) to get under 25 MB
- Set transcription.max_audio_bytes to a lower value so oversized input is rejected earlier by the manager with the 'global max' message instead
- 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
- Check byte length before calling transcribe(); reply to the user instead of throwing
- Set transcription.max_audio_bytes at or below 25 MB so the manager rejects early with one consistent message
- Downsample to 16 kHz mono Opus/FLAC at ingest — voice stays intelligible well under the cap
- Block audio documents (not voice notes) over the cap at the channel layer
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
- Audio file too large ({} bytes, global max {})
- Audio file too large ({} bytes, local_whisper max {})
- audio download exceeds {} byte limit
- audio exceeds {} byte limit for message {message_id}
- Google STT does not support '.{ext}' input
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/71136b9cf11d42dd.
Report an issue: GitHub.