Hmbown/CodeWhale · error
speech synthesis requires provider 'xiaomi-mimo' (current: {
Error message
speech synthesis requires provider 'xiaomi-mimo' (current: {}) What it means
`synthesize_speech` implements Xiaomi MiMo's TTS chat-completions surface and is hard-gated to the `xiaomi-mimo` provider; the very first check compares `self.api_provider` against `ApiProvider::XiaomiMimo` and bails for anything else. The speech tool (`tools/speech.rs`) and the top-level speech command (`lib.rs`) both route through this method.
Source
Thrown at crates/tui/src/client.rs:2337
"provider catalog refresh failed; keeping existing rows"
);
}
}
});
}
/// Generate speech with Xiaomi MiMo TTS models.
///
/// The spoken text is placed in an `assistant` message because Xiaomi
/// MiMo's TTS chat-completions surface expects that shape. The optional
/// `instruction` is a `user` message that controls style, voice design, or
/// 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 = requestView on GitHub (pinned to 8880682c63)
Solutions
- Switch the active provider to xiaomi-mimo (`provider = "xiaomi-mimo"` in config, or the in-app provider switcher) and re-run the speech command.
- Use an external TTS integration instead if you need speech on other providers — this client path is Xiaomi MiMo-only by design.
- If embedding programmatically, construct the client bound to `ApiProvider::XiaomiMimo` before calling `synthesize_speech`.
Example fix
# before provider = "deepseek" # after provider = "xiaomi-mimo"
Defensive patterns
Strategy: validation
Validate before calling
fn can_synthesize_speech(provider: ApiProvider) -> bool {
provider == ApiProvider::XiaomiMimo
} Prevention
- Hide or disable the speech command in the UI unless the active provider is xiaomi-mimo.
- When embedding, check `client.api_provider == ApiProvider::XiaomiMimo` before building speech features.
- Surface the provider requirement in the command's help text.
When it happens
Trigger: Running the speech-synthesis command while the active provider is `deepseek`, `anthropic`, `openai`, or any custom provider — the request is rejected before model/text validation or any network call.
Common situations: Trying `/speech` or the TTS tool while in a normal coding session on another provider; switching providers in config but expecting TTS to work generically; embedding the client and calling `synthesize_speech` on a general-purpose client.
Related errors
- Model '{model}' requires a voice design prompt. Pass --voice
- Model '{model}' requires cloned voice data. Pass --clone-voi
- Speech model cannot be empty
- Speech text cannot be empty
- Speech synthesis failed: HTTP {status}: {error_text}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/478fda91b6c1cacd.
Report an issue: GitHub.