zeroclaw-labs/zeroclaw · warning
Google STT does not support '.{ext}' input
Error message
Google STT does not support '.{ext}' input What it means
GoogleSttProvider::transcribe() maps the file extension to a Google Speech-to-Text encoding enum and only accepts flac, wav, ogg, opus, mp3, and webm. Any other extension bails before any API call. Note the gap versus the shared validate_audio(): formats like m4a/mp4/mpga pass the 25 MB/format gate (mime_for_audio accepts them for Whisper-compatible APIs) but Google's provider rejects them right after.
Source
Thrown at crates/zeroclaw-channels/src/transcription.rs:704
.into_iter()
.map(String::from)
.collect()
}
async fn transcribe(&self, audio_data: &[u8], file_name: &str) -> Result<String> {
let (normalized_name, _) = validate_audio(audio_data, file_name)?;
let encoding = match normalized_name
.rsplit_once('.')
.map(|(_, e)| e.to_ascii_lowercase())
.as_deref()
{
Some("flac") => "FLAC",
Some("wav") => "LINEAR16",
Some("ogg" | "opus") => "OGG_OPUS",
Some("mp3") => "MP3",
Some("webm") => "WEBM_OPUS",
Some(ext) => bail!("Google STT does not support '.{ext}' input"),
None => bail!("Google STT requires a file extension"),
};
let audio_content =
base64::Engine::encode(&base64::engine::general_purpose::STANDARD, audio_data);
let request_body = serde_json::json!({
"config": {
"encoding": encoding,
"languageCode": &self.language_code,
"enableAutomaticPunctuation": true,
},
"audio": {
"content": audio_content,
}
});
let resp = selfView on GitHub (pinned to 88bb9c8533)
Solutions
- Route m4a/mp4/mpga inputs to a provider that accepts them (groq, openai) — set the agent's transcription_provider accordingly
- Convert the audio before transcribing: ffmpeg -i in.m4a -ar 16000 -ac 1 out.flac
- Add a per-extension provider selection at the channel layer so Google only receives its supported formats
Example fix
// before: .m4a sent to google provider -> error let text = manager.transcribe_with_provider(&audio, "memo.m4a", "google").await?; // after: convert first let flac = transcode_to_flac(&audio)?; let text = manager.transcribe_with_provider(&flac, "memo.flac", "google").await?;
Defensive patterns
Strategy: validation
Validate before calling
const GOOGLE_STT_EXTS: &[&str] = &["flac", "wav", "ogg", "opus", "mp3", "webm"];
fn google_stt_accepts(file_name: &str) -> bool {
file_name.rsplit_once('.').map(|(_, e)| e.to_ascii_lowercase())
.is_some_and(|e| GOOGLE_STT_EXTS.contains(&e.as_str()))
} Type guard
fn google_stt_accepts(file_name: &str) -> bool {
let ext = file_name.rsplit_once('.')
.map(|(_, e)| e.to_ascii_lowercase())
.unwrap_or_default();
matches!(ext.as_str(), "flac" | "wav" | "ogg" | "opus" | "mp3" | "webm")
} Prevention
- Remember m4a/mp4/mpga pass the shared format check but Google rejects them — validate against Google's own list before dispatching
- Route by extension: m4a -> groq/openai, flac/wav -> any provider
- Convert at ingest with ffmpeg to flac for a format every provider accepts
When it happens
Trigger: transcribe() on the google provider with a file_name whose extension is not flac/wav/ogg/opus/mp3/webm — most commonly .m4a (iPhone voice memos), .mp4, .mpga, or .aac. The error message names the exact rejected extension.
Common situations: iPhone/Android voice notes recorded as .m4a routed to the google provider while other formats work fine; switching a working Groq/OpenAI setup to Google and suddenly m4a inputs fail; users sending audio as video-less .mp4 containers.
Related errors
- Google STT requires a file extension
- Google STT API error ({}): {}
- Audio file too large ({} bytes, max {MAX_AUDIO_BYTES})
- Audio file too large ({} bytes, local_whisper max {})
- Audio file too large ({} bytes, global max {})
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/2b5c1f7f94840ae3.
Report an issue: GitHub.