aaif-goose/goose · warning

Model not found: {}

Error message

Model not found: {}

What it means

LocalModelRegistry::delete_model builds a deletion plan via deletion_plan, which looks the id up with get_model; if no registry entry carries that id it bails with 'Model not found'. Ids are synthesized from repo_id plus quantization (model_id_from_repo), so near-miss ids are the usual cause. Nothing is deleted when this fires.

Source

Thrown at crates/goose-local-inference/src/local_model_registry.rs:578

        let plan = self.deletion_plan(id)?;
        delete_model_artifacts(&plan)?;

        if is_featured_model(id) {
            if let Some(entry) = self.models.iter_mut().find(|m| m.id == id) {
                entry.local_path = Paths::in_data_dir("models").join(&entry.filename);
                entry.storage = LocalModelStorage::GooseManaged;
                entry.shard_files.clear();
            }
            self.save()
        } else {
            self.remove_model(id)
        }
    }

    fn deletion_plan(&self, id: &str) -> Result<ModelDeletionPlan> {
        let entry = self
            .get_model(id)
            .ok_or_else(|| anyhow::anyhow!("Model not found: {}", id))?;
        let mmproj_path = entry.mmproj_path.clone();
        let other_uses_mmproj = mmproj_path.as_ref().is_some_and(|target| {
            self.models
                .iter()
                .any(|m| m.id != id && m.is_downloaded() && m.mmproj_path.as_ref() == Some(target))
        });

        Ok(ModelDeletionPlan {
            all_paths: entry.all_local_paths().map(|p| p.to_path_buf()).collect(),
            primary_path: entry.local_path.clone(),
            mmproj_path,
            delete_mmproj: entry.storage == LocalModelStorage::GooseManaged && !other_uses_mmproj,
        })
    }

    pub fn get_model(&self, id: &str) -> Option<&LocalModelEntry> {
        self.models.iter().find(|m| m.id == id)
    }

View on GitHub (pinned to 3810898a74)

Solutions

  1. Check has_model(id) or refresh from list_models() and pass the exact stored id
  2. If your delete should be idempotent, treat this specific 'Model not found' as success
  3. Reconcile the UI model list with the registry before offering delete actions

Example fix

// before
registry.delete_model(model_id)?;

// after: idempotent delete with a precise error
if !registry.has_model(model_id) {
    log::debug!("model {model_id} already gone");
    return Ok(());
}
registry.delete_model(model_id)?;
Defensive patterns

Strategy: validation

Validate before calling

if !registry.has_model(model_id) {
    // stale id or double delete: refresh from list_models() or treat as done
    return Ok(());
}
registry.delete_model(model_id)?;

Type guard

fn model_id_exists(registry: &LocalModelRegistry, id: &str) -> bool {
    registry.has_model(id)
}

Try / catch

match registry.delete_model(id) {
    Err(e) if e.to_string().starts_with("Model not found") => {
        // already deleted: treat as success for idempotent flows, or refresh the list
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling delete_model with an id that was never registered, was already deleted (double-delete), or was built differently than the registry's id (different quantization suffix, casing, or owner).

Common situations: Stale UI list after a delete from another window/device; retrying a delete that already succeeded; ids reconstructed by hand instead of taken from list_models.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/4b9c8bb3fa8f7b02. Report an issue: GitHub.