{"record":{"id":"7231ee6d29afb00c","repo":"zeroclaw-labs/zeroclaw","slug":"audio-file-too-large-bytes-local-whisper-max","errorCode":null,"errorMessage":"Audio file too large ({} bytes, local_whisper max {})","messagePattern":"Audio file too large \\((.+?) bytes, local_whisper max (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/zeroclaw-channels/src/transcription.rs","lineNumber":847,"sourceCode":"        let bridge = zeroclaw_config::schema::LocalWhisperConfig {\n            url: cfg.uri.clone(),\n            bearer_token: cfg.bearer_token.clone(),\n            max_audio_bytes: cfg.max_audio_bytes,\n            timeout_secs: cfg.timeout_secs,\n        };\n        Self::from_config(alias, &bridge)\n    }\n}\n\n#[async_trait]\nimpl TranscriptionProvider for LocalWhisperProvider {\n    fn name(&self) -> &str {\n        \"local_whisper\"\n    }\n\n    async fn transcribe(&self, audio_data: &[u8], file_name: &str) -> Result<String> {\n        if audio_data.len() > self.max_audio_bytes {\n            bail!(\n                \"Audio file too large ({} bytes, local_whisper max {})\",\n                audio_data.len(),\n                self.max_audio_bytes\n            );\n        }\n\n        let (normalized_name, mime) = resolve_audio_format(file_name)?;\n\n        let client =\n            zeroclaw_config::schema::build_runtime_proxy_client(\"transcription.local_whisper\");\n\n        // to_vec() clones the buffer for the multipart payload; peak memory per\n        // call is ~2× max_audio_bytes. TODO: replace with streaming upload once\n        // reqwest supports body streaming in multipart parts.\n        let file_part = Part::bytes(audio_data.to_vec())\n            .file_name(normalized_name)\n            .mime_str(mime)?;\n","sourceCodeStart":829,"sourceCodeEnd":865,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/transcription.rs#L829-L865","documentation":"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.","triggerScenarios":"transcribe_with_provider(..., \"local_whisper\") (or an agent bound to local_whisper) with audio_data.len() exceeding the configured local_whisper.max_audio_bytes.","commonSituations":"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.","solutions":["Raise [transcription.local_whisper].max_audio_bytes if your self-hosted backend can handle the payload","Otherwise reject or compress oversized audio at the channel layer before transcribing","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"],"exampleFix":"# before\n[transcription.local_whisper]\napi_url = \"http://localhost:9000/v1/audio/transcriptions\"\nmax_audio_bytes = 10485760\n\n# after\n[transcription.local_whisper]\napi_url = \"http://localhost:9000/v1/audio/transcriptions\"\nmax_audio_bytes = 52428800","handlingStrategy":"validation","validationCode":"// Mirror your [transcription.local_whisper].max_audio_bytes at the call site\nconst LOCAL_WHISPER_MAX: usize = 10 * 1024 * 1024;\n\nfn within_local_whisper_cap(audio: &[u8]) -> bool {\n    audio.len() <= LOCAL_WHISPER_MAX\n}","typeGuard":null,"tryCatchPattern":"match manager.transcribe(&audio, name).await {\n    Ok(text) => Some(text),\n    Err(e) if e.to_string().contains(\"local_whisper max\") => {\n        channel.reply(\"Voice note exceeds the local transcription limit.\").await;\n        None\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep the three limits aligned intentionally: global max, local_whisper max, 25 MB cloud cap — effective limit is the minimum that applies","Pre-check byte size at the channel layer and reply to the user"],"tags":["local-whisper","file-size","transcription","config","pre-flight-check"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}