cjpais/Handy · warning · anyhow::Error

No model files found to delete

Error message

No model files found to delete

What it means

Delete was requested for an HF-sourced model, but neither the HF cache blob/snapshot file (including the alternate-quant single-file path) nor the model file in models_dir existed — so nothing was deleted and the operation reports that instead of silently succeeding. The HF branch deletes per-quant files (snapshot pointer + blob) so an externally emptied cache ends here.

Solutions

  1. Treat as harmless in practice — refresh/restart so download status resyncs with disk
  2. If the UI still shows the model as downloaded, restart the app to rebuild is_downloaded flags
  3. As a maintainer: make delete idempotent by treating 'nothing to delete' as success when the goal is removal
Defensive patterns

Strategy: validation

Validate before calling

// check the HF cache blob and local file before asking for a delete
let exists = hf_cached_path(&repo_id, &revision, &filename).is_some()
    || self.models_dir.join(&filename).exists();
if !exists {
    // nothing on disk — just resync status instead of erroring
    self.update_download_status()?;
    return Ok(());
}

Try / catch

match manager.delete_model(id) {
    Err(e) if e.to_string().contains("No model files found") => {
        // already gone externally — treat as success, refresh status
        manager.update_download_status()?;
        Ok(())
    }
    other => other,
}?

Prevention

When it happens

Trigger: Double-delete: a prior delete already removed the blob; user cleared the HF cache externally (huggingface-cli delete-cache or manual rm of ~/.cache/huggingface); is_downloaded flag was stale (cache emptied while app was running).

Common situations: Users reclaiming disk space by wiping the HF cache while the app still lists the model; two delete requests racing; app data migrated between machines without the cache.

Related errors


AI-assisted analysis of cjpais/Handy@fbd4e15fa1 (2026-08-17). Data as JSON: /api/errors/9c624463d3619dd8. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/src/managers/model.rs:2418

                        deleted = true;
                    }
                }
            }
            // Also remove a models-dir copy (mirror fallback / manual drop-in)
            // and any resumable partial next to it.
            for path in [
                self.models_dir.join(&model_info.filename),
                self.models_dir
                    .join(format!("{}.partial", &model_info.filename)),
            ] {
                if path.exists() {
                    info!("Deleting model file at: {:?}", path);
                    fs::remove_file(&path)?;
                    deleted = true;
                }
            }
            if !deleted {
                return Err(anyhow::anyhow!("No model files found to delete"));
            }
            // Alternate-quant entries are discovery-created (the catalog only
            // seeds defaults), so deleting one un-discovers it rather than
            // leaving a permanent "(Q4_K_M)" row in the list.
            if is_alternate_quant {
                self.available_models.lock().unwrap().remove(model_id);
            }
            self.update_download_status()?;
            let _ = self.app_handle.emit("model-deleted", model_id);
            return Ok(());
        }

        let model_path = self.models_dir.join(&model_info.filename);
        let partial_path = self
            .models_dir
            .join(format!("{}.partial", &model_info.filename));
        debug!("ModelManager: Model path: {:?}", model_path);
        debug!("ModelManager: Partial path: {:?}", partial_path);

View on GitHub (pinned to fbd4e15fa1)