Hmbown/CodeWhale · error

Speech text cannot be empty

Error message

Speech text cannot be empty

What it means

Second input validation in `synthesize_speech`: the text to speak is trimmed and must be non-empty. An empty or whitespace-only `SpeechSynthesisRequest.text` is rejected locally before any request body is built — no network round trip occurs.

Source

Thrown at crates/tui/src/client.rs:2349

    /// voice-clone performance and is not spoken verbatim.
    pub async fn synthesize_speech(
        &self,
        request: SpeechSynthesisRequest,
    ) -> Result<SpeechSynthesisResponse> {
        if self.api_provider != crate::config::ApiProvider::XiaomiMimo {
            anyhow::bail!(
                "speech synthesis requires provider 'xiaomi-mimo' (current: {})",
                self.api_provider.as_str()
            );
        }

        let model = request.model.trim().to_string();
        if model.is_empty() {
            anyhow::bail!("Speech model cannot be empty");
        }
        let text = request.text.trim().to_string();
        if text.is_empty() {
            anyhow::bail!("Speech text cannot be empty");
        }

        let audio_format = normalize_audio_format(&request.audio_format);
        let model = wire_model_for_provider_route(self.api_provider, &self.base_url, &model);
        let model_lower = model.to_ascii_lowercase();
        let instruction = request
            .instruction
            .as_deref()
            .map(str::trim)
            .filter(|value| !value.is_empty());
        let voice = request
            .voice
            .as_deref()
            .map(str::trim)
            .filter(|value| !value.is_empty())
            .map(str::to_string);

        if model_lower.contains("voicedesign") && instruction.is_none() {

View on GitHub (pinned to 8880682c63)

Solutions

  1. Supply non-blank text to speak after the options: `/speech --model xiaomi-mimo-tts "Narrate this"`.
  2. Guard the caller side: skip or error early when the trimmed input is empty instead of invoking the API.
  3. When piping text, fail fast on empty stdin before calling the tool.

Example fix

# before
/speech --model xiaomi-mimo-tts "   "
# after
/speech --model xiaomi-mimo-tts "Weekly report summary..."
Defensive patterns

Strategy: validation

Validate before calling

fn speech_request_valid(model: &str, text: &str) -> bool {
    !model.trim().is_empty() && !text.trim().is_empty()
}

Type guard

fn non_blank(s: &str) -> Option<&str> {
    let t = s.trim();
    (!t.is_empty()).then_some(t)
}

Prevention

When it happens

Trigger: Running the speech command with no positional text argument; passing a string of only spaces/newlines; scripting with an empty text variable; quoting errors that swallow the intended text (`/speech --model m ""`).

Common situations: Shell quoting mistakes dropping the argument; pipelines feeding the tool an empty string (e.g. `$(grep -q ... && echo)` producing nothing); UI sending the placeholder text instead of user input.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/4ad2b9b37f0a6290. Report an issue: GitHub.