{"record":{"id":"b74e3940d8864177","repo":"zeroclaw-labs/zeroclaw","slug":"assemblyai-transcription-failed","errorCode":null,"errorMessage":"AssemblyAI transcription failed: {}","messagePattern":"AssemblyAI transcription failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/transcription.rs","lineNumber":590,"sourceCode":"                let error_msg = poll_body[\"error\"].as_str().unwrap_or(\"unknown poll error\");\n                bail!(\"AssemblyAI poll error ({}): {}\", poll_status, error_msg);\n            }\n\n            let status_str = poll_body[\"status\"].as_str().unwrap_or(\"unknown\");\n\n            match status_str {\n                \"completed\" => {\n                    let text = poll_body[\"text\"]\n                        .as_str()\n                        .context(\"AssemblyAI response missing 'text'\")?\n                        .to_string();\n                    return Ok(text);\n                }\n                \"error\" => {\n                    let error_msg = poll_body[\"error\"]\n                        .as_str()\n                        .unwrap_or(\"unknown transcription error\");\n                    bail!(\"AssemblyAI transcription failed: {}\", error_msg);\n                }\n                _ => {}\n            }\n        }\n\n        bail!(\"AssemblyAI transcription timed out after 180s\")\n    }\n}\n\n// ── GoogleSttProvider ───────────────────────────────────────────\n\n/// Google Cloud Speech-to-Text API transcription_provider.\npub struct GoogleSttProvider {\n    alias: String,\n    api_key: String,\n    language_code: String,\n}\n","sourceCodeStart":572,"sourceCodeEnd":608,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/transcription.rs#L572-L608","documentation":"The AssemblyAI poll loop received status \"error\" for the transcript job: the job was accepted and processed but failed server-side. The 'error' field from the poll body is embedded when present ('unknown transcription error' otherwise). This is terminal — retrying the same audio usually fails again unless the root cause (media format, quota, duration) is fixed.","triggerScenarios":"AssemblyAI sets the transcript's status to \"error\": unsupported or corrupt media (e.g. a video file misrouted as audio, zero-byte audio, unsupported codec), audio duration exceeding the account's limit, or account quota/billing problems.","commonSituations":"Codec edge cases (unusual AAC/AMR variants from cheap phones), silent/corrupt voice messages downloaded truncated by a proxy, free-tier duration caps exceeded by long recordings.","solutions":["Read the embedded error message — AssemblyAI names the exact cause (e.g. 'unsupported media format', 'duration limit exceeded')","Re-encode the audio to mp3/wav/flac with ffmpeg and retry","For duration-limit errors, split long audio into shorter segments","Check the AssemblyAI dashboard for the failed transcript and account quota"],"exampleFix":"# re-encode a problematic voice note before transcribing\nffmpeg -i input.amr -ar 16000 -ac 1 -c:a libmp3lame -b:a 48k input.mp3","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match provider.transcribe(&audio, name).await {\n    Ok(text) => Ok(text),\n    Err(e) if e.to_string().contains(\"AssemblyAI transcription failed\") => {\n        // terminal job failure: do NOT blind-retry; read the embedded reason first\n        anyhow::bail!(\"assemblyai rejected the media: {e}\")\n    }\n    other => other,\n}","preventionTips":["Re-encode to a mainstream codec before sending — most job-level errors are media problems","Reject zero-byte or truncated downloads at the channel layer before transcription","Split long recordings; duration caps fail at the job level"],"tags":["assemblyai","transcription","media-format","terminal-failure"],"backgroundTag":"speech-to-text-api-error","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}