aaif-goose/goose · error
Local Whisper model not configured
Error message
Local Whisper model not configured
What it means
Local dictation (feature `local-inference`) reads the Whisper model id from the goose config key LOCAL_WHISPER_MODEL (whisper.rs:11). transcribe_local fails with this error when that key is missing or its value is not a string — before any model lookup or transcription starts.
Source
Thrown at crates/goose/src/dictation/providers.rs:142
.and_then(|v| v.as_str().map(|s| s.to_string()))
.and_then(|id| super::whisper::get_model(&id))
.is_some_and(|m| m.is_downloaded()),
_ => {
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());
View on GitHub (pinned to 3810898a74)
Solutions
- Set the key to one of the supported model ids: tiny, base, small, or medium — e.g. `goose config set --params LOCAL_WHISPER_MODEL tiny`
- Use whisper::recommend_model() to pick an id matching your hardware (small on GPU/Metal, base/tiny on CPU)
- Confirm with is_configured(DictationProvider::Local) before invoking transcription
Example fix
# before # LOCAL_WHISPER_MODEL unset -> transcribe_local() errors # after goose config set --params LOCAL_WHISPER_MODEL small
Defensive patterns
Strategy: validation
Validate before calling
use goose::config::Config;
use goose::dictation::whisper::LOCAL_WHISPER_MODEL_CONFIG_KEY;
fn local_whisper_ready() -> bool {
Config::global()
.get(LOCAL_WHISPER_MODEL_CONFIG_KEY, false)
.ok()
.and_then(|v| v.as_str().map(|s| s.to_string()))
.is_some()
}
// or use the built-in readiness check that also verifies the model is downloaded:
// is_configured(DictationProvider::Local) Type guard
fn local_whisper_ready() -> bool {
Config::global()
.get("LOCAL_WHISPER_MODEL", false)
.ok()
.and_then(|v| v.as_str().map(|s| s.to_string()))
.is_some()
} Prevention
- Gate the Local dictation option in the UI on is_configured(DictationProvider::Local)
- Store the model id as a plain string in config — never a number or bool
- On fresh installs, run model selection (recommend_model) before enabling local dictation
When it happens
Trigger: Using DictationProvider::Local without ever configuring the model: Config::global().get(LOCAL_WHISPER_MODEL, ...) returns None or a non-string value, so the `.ok()`/`as_str()` chain yields None.
Common situations: Fresh installs where local dictation was selected but no model was chosen; the config key was deleted; the value was written as a non-string type (number/bool) in the config file.
Related errors
- Unknown model: {}
- Failed to lock transcriber: {}
- GOOSE_SERVER__SECRET_KEY is required for goose serve
- GOOSE_SERVER__SECRET_KEY must be set when using GOOSE_EXTERN
- No command provided in extension string
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/29d6165255b5584c.
Report an issue: GitHub.