Hmbown/CodeWhale · error · anyhow::Error
Speech text cannot be empty
Error message
Speech text cannot be empty
What it means
Input guard on the speech-synthesis path in client.rs: after the provider check (xiaomi-mimo only) and model check, the trimmed request text must be non-empty. A blank text string is rejected before any HTTP request is made.
Solutions
- Supply non-empty text in SpeechSynthesisRequest.text.
- If piping input, verify the upstream command actually produced output before invoking TTS.
- Check clipboard/file sources are non-empty before passing them.
Example fix
// before
let text = std::env::var("TTS_TEXT")?; // may be empty
// after
let text = std::env::var("TTS_TEXT")?;
if text.trim().is_empty() { anyhow::bail!("no text to synthesize"); } Defensive patterns
Strategy: validation
Validate before calling
if request.text.trim().is_empty() {
return Err(anyhow::anyhow!("speech text cannot be empty"));
} Try / catch
match result {
Err(e) if e.to_string() == "Speech text cannot be empty" => {
eprintln!("No text supplied to synthesize; check your input source");
}
r => r?,
} Prevention
- Validate piped/clipboard input is non-empty before calling TTS.
- Fail the upstream pipeline early when a source produces no text.
When it happens
Trigger: Calling speech synthesis with text = "" or only whitespace (e.g. piping empty stdin into a TTS command).
Common situations: Shell pipeline producing no stdin data (echo "" | ... tts); clipboard read returning empty; upstream command failure silently feeding empty text.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Speech model cannot be empty
- Model ' ' requires a voice design prompt. Pass…
- persisted image input must contain an image
- speech requires a TTS model
- Speech text cannot be empty
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/4ad2b9b37f0a6290.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/client.rs:3336
&self,
request: SpeechSynthesisRequest,
) -> Result<SpeechSynthesisResponse> {
let _inference = self.acquire_remote_control_inference_permit().await;
let _permit = self.acquire_provider_request_permit().await;
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 = self.wire_model_for_route(&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 73e0f67d83)