aaif-goose/goose · error
Unknown model: {}
Error message
Unknown model: {} What it means
transcribe_local resolves LOCAL_WHISPER_MODEL through whisper::get_model, which is an exact-match lookup over the static MODELS catalog containing only the ids "tiny", "base", "small", and "medium" (whisper.rs:61-79). Any other string returns None and becomes this error. Note the catalog is stricter than whisper's internal Config fallback, which would silently fall back to tiny for unknown ids.
Source
Thrown at crates/goose/src/dictation/providers.rs:145
_ => {
let def = get_provider_def(provider);
config.get_secret::<String>(def.config_key).is_ok()
}
}
}
#[cfg(feature = "local-inference")]
pub async fn transcribe_local(audio_bytes: Vec<u8>) -> Result<String> {
tokio::task::spawn_blocking(move || {
let config = Config::global();
let model_id = config
.get(LOCAL_WHISPER_MODEL_CONFIG_KEY, false)
.ok()
.and_then(|v| v.as_str().map(|s| s.to_string()))
.ok_or_else(|| anyhow::anyhow!("Local Whisper model not configured"))?;
let model = super::whisper::get_model(&model_id)
.ok_or_else(|| anyhow::anyhow!("Unknown model: {}", model_id))?;
let model_path = model.local_path();
let mut transcriber_lock = LOCAL_TRANSCRIBER
.lock()
.map_err(|e| anyhow::anyhow!("Failed to lock transcriber: {}", e))?;
let model_path_str = model_path.to_string_lossy().to_string();
let needs_reload = match transcriber_lock.as_ref() {
None => true,
Some((cached_path, _)) => cached_path != &model_path_str,
};
if needs_reload {
tracing::info!("Loading Whisper model from: {}", model_path.display());
let transcriber = super::whisper::WhisperTranscriber::new_with_tokenizer(
&model_id,
&model_path,View on GitHub (pinned to 3810898a74)
Solutions
- Set LOCAL_WHISPER_MODEL to exactly one of: tiny, base, small, medium
- Pick programmatically with recommend_model() or list valid ids via available_models()
Example fix
# before goose config set --params LOCAL_WHISPER_MODEL large-v3 # after goose config set --params LOCAL_WHISPER_MODEL small
Defensive patterns
Strategy: validation
Validate before calling
use goose::dictation::whisper::{available_models, get_model};
fn model_id_supported(id: &str) -> bool {
get_model(id).is_some()
}
// validate before transcribing, or offer the valid set:
let ids: Vec<&str> = available_models().iter().map(|m| m.id).collect(); Type guard
fn model_id_supported(id: &str) -> bool {
goose::dictation::whisper::get_model(id).is_some() // ids: tiny | base | small | medium
} Prevention
- Restrict the config UI to a dropdown of available_models() ids
- Trim whitespace and lowercase user input before storing it as LOCAL_WHISPER_MODEL
- Do not copy model names from OpenAI docs — local ids are only tiny/base/small/medium
When it happens
Trigger: LOCAL_WHISPER_MODEL set to an unsupported value: "large", "whisper-small", "small.en", "Small" (case-sensitive), or a value with trailing whitespace.
Common situations: Copying a model name from OpenAI's API docs (large-v3, whisper-1) instead of goose's local ids; hand-editing the config file; case or whitespace mistakes.
Related errors
- Local Whisper model not configured
- {} must be at least 4096
- Invalid OPENAI_BASE_URL '{}': {}
- Provider '{}' has dynamic_models: false but no static models
- Invalid base URL '{}': {}
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/a96c15f9f43024df.
Report an issue: GitHub.