aaif-goose/goose · error
Model not found
Error message
Model not found
What it means
delete_model() looks up model_id in the registry and bails with 'Model not found' when registry.get_model(model_id) is None. The registry only contains models previously registered by the download flow (llamacpp ids look like 'owner/repo:QUANT', mlx ids like 'owner/repo'). This is a plain not-found condition, not corruption. The lookup happens under the lock, so the model must match exactly, byte for byte.
Source
Thrown at crates/goose-local-inference/src/management.rs:206
pub fn download_progress(model_id: &str) -> Result<Option<LocalInferenceDownloadProgressDto>> {
Ok(get_download_manager()
.get_progress(&format!("{}-model", model_id))
.map(download_progress_to_dto))
}
pub fn cancel_download(model_id: &str) -> Result<()> {
let manager = get_download_manager();
manager.cancel_download(&format!("{}-model", model_id))?;
let _ = manager.cancel_download(&format!("{}-mmproj", model_id));
Ok(())
}
pub fn delete_model(model_id: &str) -> Result<()> {
let mut registry = get_registry()
.lock()
.map_err(|_| anyhow!("Failed to acquire registry lock"))?;
if registry.get_model(model_id).is_none() {
anyhow::bail!("Model not found");
}
registry.delete_model(model_id)
}
pub fn model_exists(model_id: &str) -> Result<bool> {
let registry = get_registry()
.lock()
.map_err(|_| anyhow!("Failed to acquire registry lock"))?;
Ok(registry.get_model(model_id).is_some())
}
pub async fn evict_model(model_id: &str) -> Result<()> {
crate::evict_model(model_id)
.await
.map(|_| ())
.map_err(|error| anyhow!(error.to_string()))
}
View on GitHub (pinned to 3810898a74)
Solutions
- Call list_models() and use the exact id it returns (note the 'owner/repo:QUANT' shape for llama.cpp models).
- Confirm the process uses the same data directory / GOOSE_HOME as the one where the model was downloaded.
- Make deletion idempotent in the caller: treat 'Model not found' as success when reconciling state.
- If the model directory exists on disk but is not listed, re-download or manually remove the files — the registry is the source of truth for delete_model.
Example fix
// before
management::delete_model(&model_id)?; // errors 'Model not found' on stale id
// after: reconcile against the registry first
let models = management::list_models().await?;
let exact = models.models.iter().find(|m| m.id == model_id)
.map(|m| m.id.clone());
if let Some(id) = exact {
management::delete_model(&id)?;
} Defensive patterns
Strategy: validation
Validate before calling
let models = management::list_models().await?;
let exists = models.models.iter().any(|m| m.id == model_id);
if !exists {
return Ok(()); // already gone — treat delete as idempotent
}
management::delete_model(model_id)?; Type guard
fn is_registered_model_id(models: &LocalInferenceModelsListResponse, id: &str) -> bool {
models.models.iter().any(|m| m.id == id)
} Try / catch
match management::delete_model(model_id) {
Ok(()) => Ok(()),
Err(e) if e.to_string().contains("Model not found") => Ok(()), // idempotent delete
Err(e) => Err(e),
} Prevention
- Always source model ids from list_models(), never construct them by hand.
- Remember llama.cpp ids embed the quantization: 'owner/repo:Q4_K_M'.
- Verify both processes use the same GOOSE_HOME/data dir before cross-checking ids.
- Make scripted deletes idempotent by swallowing 'Model not found'.
When it happens
Trigger: Deleting with a malformed or non-registered id: passing 'Qwen/Qwen2.5-7B' (no :Q4_K_M quant suffix) for a llamacpp model; deleting a model that was already deleted (double-delete); passing an id from a different data dir / GOOSE_HOME than the one the registry persists in; case or whitespace mismatch.
Common situations: UI holds a stale list after the model was removed elsewhere; user hand-copies an id and drops the quantization suffix; registry.json was recreated after a data-dir wipe or migration; scripted cleanup re-running after partial success.
Related errors
- Model not found: {}
- llama.cpp model '{}' is missing a quantization
- Resolved GGUF model has no local files
- Failed to acquire registry lock
- Unknown local inference backend '{}'
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/5c0536176d532882.
Report an issue: GitHub.