Hmbown/CodeWhale · error · anyhow::Error

Use either --clone-voice or --voice for cloned voice data, n

Error message

Use either --clone-voice or --voice for cloned voice data, not both

What it means

Mutual-exclusion guard for cloned-voice input. `--clone-voice` (a path to an mp3/wav sample) and `--voice` (a voice id or a data:audio/... data-URI) are two alternative ways to supply cloned voice data; supplying both is ambiguous, so the CLI refuses the combination before encoding anything.

Source

Thrown at crates/tui/src/lib.rs:7369

        json: json_output,
    } = args;

    if config.api_provider() != ApiProvider::XiaomiMimo {
        bail!(
            "`speech` requires provider = \"xiaomi-mimo\" (current: {}). Run with `--provider xiaomi-mimo` or set it in config.",
            config.api_provider().as_str()
        );
    }

    if text.trim().is_empty() {
        bail!("Speech text cannot be empty");
    }
    let voice_is_data_uri = voice
        .as_deref()
        .map(str::trim)
        .is_some_and(|value| value.starts_with("data:audio/"));
    if clone_voice.is_some() && voice.is_some() {
        bail!("Use either --clone-voice or --voice for cloned voice data, not both");
    }
    let model = infer_speech_model(
        model.as_deref(),
        clone_voice.is_some() || voice_is_data_uri,
        voice_prompt.is_some(),
    );
    let model_lower = model.to_ascii_lowercase();
    if !model_lower.contains("tts") {
        bail!(
            "speech requires a TTS model (examples: {}); got {model}",
            SPEECH_MODEL_EXAMPLES.join(", ")
        );
    }
    let is_voice_design = model_lower.contains("voicedesign");
    let is_voice_clone = model_lower.contains("voiceclone");

    let instruction = combine_speech_instructions(instruction, voice_prompt);
    if is_voice_design

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Cloning from a local file: keep `--clone-voice <mp3|wav>` and drop `--voice`
  2. Already have a data:audio/... data-URI: keep `--voice` and drop `--clone-voice`
  3. Plain named voice for non-clone models: `--voice` alone is fine; --clone-voice exists only for cloning

Example fix

// before
$ codewhale speech --clone-voice sample.mp3 --voice data:audio/mp3;base64,...
Error: Use either --clone-voice or --voice for cloned voice data, not both

// after
$ codewhale speech --clone-voice sample.mp3
Defensive patterns

Strategy: validation

Validate before calling

if [ -n "$CLONE_VOICE" ] && [ -n "$VOICE" ]; then
  echo 'pass only one of --clone-voice / --voice' >&2; exit 2
fi

Prevention

When it happens

Trigger: `codewhale speech` invoked with both `--clone-voice <path>` and `--voice <value>` present (clone_voice.is_some() && voice.is_some()). The check runs before data-URI detection on --voice, so even a plain voice id conflicts with --clone-voice.

Common situations: Long speech commands grown flag by flag while prototyping; templates that always set --voice and later add --clone-voice for cloning experiments.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


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