{"record":{"id":"231ea4f63dcb7dd5","repo":"Hmbown/CodeWhale","slug":"voice-clone-sample-is-too-large-after-base64-encod","errorCode":null,"errorMessage":"voice clone sample is too large after base64 encoding ({} bytes > 10 MB)","messagePattern":"voice clone sample is too large after base64 encoding \\((.+?) bytes > 10 MB\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/speech.rs","lineNumber":406,"sourceCode":"            path.display()\n        ))\n    })?;\n\n    voice_clone_data_uri_from_bytes(path, &bytes)\n        .map_err(|err| ToolError::invalid_input(err.to_string()))\n}\n\npub(crate) fn encode_voice_clone_sample_data_uri(path: &Path) -> anyhow::Result<String> {\n    let bytes = std::fs::read(path)\n        .with_context(|| format!(\"Failed to read voice clone sample {}\", path.display()))?;\n\n    voice_clone_data_uri_from_bytes(path, &bytes)\n}\n\nfn voice_clone_data_uri_from_bytes(path: &Path, bytes: &[u8]) -> anyhow::Result<String> {\n    let base64_audio = general_purpose::STANDARD.encode(bytes);\n    if base64_audio.len() > VOICE_CLONE_BASE64_MAX_BYTES {\n        anyhow::bail!(\n            \"voice clone sample is too large after base64 encoding ({} bytes > 10 MB)\",\n            base64_audio.len()\n        );\n    }\n\n    let extension = path\n        .extension()\n        .and_then(|value| value.to_str())\n        .unwrap_or_default()\n        .to_ascii_lowercase();\n    let mime = match extension.as_str() {\n        \"mp3\" => \"audio/mpeg\",\n        \"wav\" => \"audio/wav\",\n        other => {\n            anyhow::bail!(\"unsupported voice clone sample extension '{other}'. Use .mp3 or .wav.\");\n        }\n    };\n","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/tools/speech.rs#L388-L424","documentation":"encode_voice_clone_sample_data_uri refuses voice samples whose base64 encoding exceeds VOICE_CLONE_BASE64_MAX_BYTES (10 MiB of base64, i.e. roughly 7.5 MiB / 7,864,320 raw bytes, since base64 inflates by 4/3). The whole sample is embedded as a data URI, so this cap keeps the request payload bounded.","triggerScenarios":"Calling the voice-clone path with a long audio file: a 30+ minute wav, an uncompressed pcm wav of a few minutes, or any file over about 7.5 MiB before encoding.","commonSituations":"Uncompressed .wav recordings from DAWs or recorders (wav is large per minute); reusing full podcast episodes as clone samples; samples normalized to wav instead of compressed mp3.","solutions":["Trim the sample to 10-30 seconds of clean speech; clone quality does not improve materially with much more.","Convert to mp3 (or compressed wav) so the raw size drops well under ~7.5 MiB before base64.","Check file size before calling: raw_len.saturating_mul(4).div_ceil(3) must be <= 10 * 1024 * 1024."],"exampleFix":"// before\nlet uri = encode_voice_clone_sample_data_uri(&sample_path)?; // 20-minute wav fails\n\n// after\nconst MAX_B64: u64 = 10 * 1024 * 1024;\nlet raw = fs::metadata(&sample_path)?.len();\nif raw.saturating_mul(4).div_ceil(3) > MAX_B64 {\n    bail!(\"sample too large ({raw} bytes); trim to <=30s or convert to mp3\");\n}\nlet uri = encode_voice_clone_sample_data_uri(&sample_path)?;","handlingStrategy":"validation","validationCode":"const VOICE_CLONE_BASE64_MAX_BYTES: u64 = 10 * 1024 * 1024;\n\nfn sample_within_limit(path: &Path) -> Result<bool> {\n    let raw = fs::metadata(path)?.len();\n    Ok(raw.saturating_mul(4).div_ceil(3) <= VOICE_CLONE_BASE64_MAX_BYTES)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep clone samples to 10-30 seconds of speech; more audio rarely improves the clone.","Prefer mp3 over uncompressed wav for samples (wav inflates ~10x per minute).","Check size before encoding: base64 adds 1/3, so the raw file must be under about 7.5 MiB."],"tags":["speech","voice-clone","file-size","base64","rust"],"backgroundTag":"payload-too-large","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}