Hmbown/CodeWhale · error

voice clone sample is too large after base64 encoding ({} by

Error message

voice clone sample is too large after base64 encoding ({} bytes > 10 MB)

What it means

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.

Source

Thrown at crates/tui/src/tools/speech.rs:406

            path.display()
        ))
    })?;

    voice_clone_data_uri_from_bytes(path, &bytes)
        .map_err(|err| ToolError::invalid_input(err.to_string()))
}

pub(crate) fn encode_voice_clone_sample_data_uri(path: &Path) -> anyhow::Result<String> {
    let bytes = std::fs::read(path)
        .with_context(|| format!("Failed to read voice clone sample {}", path.display()))?;

    voice_clone_data_uri_from_bytes(path, &bytes)
}

fn voice_clone_data_uri_from_bytes(path: &Path, bytes: &[u8]) -> anyhow::Result<String> {
    let base64_audio = general_purpose::STANDARD.encode(bytes);
    if base64_audio.len() > VOICE_CLONE_BASE64_MAX_BYTES {
        anyhow::bail!(
            "voice clone sample is too large after base64 encoding ({} bytes > 10 MB)",
            base64_audio.len()
        );
    }

    let extension = path
        .extension()
        .and_then(|value| value.to_str())
        .unwrap_or_default()
        .to_ascii_lowercase();
    let mime = match extension.as_str() {
        "mp3" => "audio/mpeg",
        "wav" => "audio/wav",
        other => {
            anyhow::bail!("unsupported voice clone sample extension '{other}'. Use .mp3 or .wav.");
        }
    };

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Trim the sample to 10-30 seconds of clean speech; clone quality does not improve materially with much more.
  2. Convert to mp3 (or compressed wav) so the raw size drops well under ~7.5 MiB before base64.
  3. Check file size before calling: raw_len.saturating_mul(4).div_ceil(3) must be <= 10 * 1024 * 1024.

Example fix

// before
let uri = encode_voice_clone_sample_data_uri(&sample_path)?; // 20-minute wav fails

// after
const MAX_B64: u64 = 10 * 1024 * 1024;
let raw = fs::metadata(&sample_path)?.len();
if raw.saturating_mul(4).div_ceil(3) > MAX_B64 {
    bail!("sample too large ({raw} bytes); trim to <=30s or convert to mp3");
}
let uri = encode_voice_clone_sample_data_uri(&sample_path)?;
Defensive patterns

Strategy: validation

Validate before calling

const VOICE_CLONE_BASE64_MAX_BYTES: u64 = 10 * 1024 * 1024;

fn sample_within_limit(path: &Path) -> Result<bool> {
    let raw = fs::metadata(path)?.len();
    Ok(raw.saturating_mul(4).div_ceil(3) <= VOICE_CLONE_BASE64_MAX_BYTES)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/231ea4f63dcb7dd5. Report an issue: GitHub.