Zackriya-Solutions/meetily · warning · anyhow::Error
Can only delete corrupted or available models. Model
Error message
Can only delete corrupted or available models. Model '{}' has status: {:?} What it means
delete_model only handles ModelStatus::Corrupted and ModelStatus::Available; every other status falls to the catch-all arm and is rejected with the current status shown. This is a deliberate state-machine guard: you cannot delete what is Missing (nothing on disk), Downloading (an active task owns the file), or Error (recover by re-downloading instead).
Solutions
- For Downloading: cancel the download first (set the cancel flag / cancel_download command) or wait for it to finish, then delete
- For Missing: nothing to delete — refresh the model list; the action already succeeded earlier
- For Error: re-run download_model to overwrite the bad file instead of deleting, or remove the file manually and rescan
Defensive patterns
Strategy: validation
Validate before calling
const models = await invoke<ModelInfo[]>('get_whisper_models');
const m = models.find(x => x.name === modelName);
if (!m) throw new Error('Unknown model');
if (m.status !== 'Available' && m.status !== 'Corrupted') {
throw new Error(`Cannot delete while status is ${m.status}. Cancel the download or refresh.`);
}
await invoke('delete_model', { modelName }); Type guard
const isDeletable = (s: string): boolean => s === 'Available' || s === 'Corrupted';
Try / catch
try {
await invoke('delete_model', { modelName });
} catch (e) {
if (String(e).includes('Can only delete')) {
// Downloading -> cancel first; Missing -> refresh list; Error -> re-download instead
refreshModelList();
} else { throw e; }
} Prevention
- Hide or disable Delete for rows whose status is not Available/Corrupted
- Cancel an active download before offering deletion of the same model
- Refresh the model list after every delete/cancel to prevent stale-row double actions
When it happens
Trigger: Calling delete_model while download_model streams the same model (Downloading); double-delete where the first call already set status Missing; calling delete on a model whose status is Error.
Common situations: User hits Delete during an active download; UI row not refreshed after a delete so the action fires twice; trying to 'clear' an Error state by deleting it.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Model has error
- Model is corrupted and cannot be loaded
- Model is currently downloading
- Model ' ' not found
- Unsupported model
AI-assisted analysis of Zackriya-Solutions/meetily@a2cb62e827 (2026-08-16).
Data as JSON: /api/errors/06ea8214b1480955.
Report an issue: GitHub.
Appendix: source
Thrown at frontend/src-tauri/src/whisper_engine/whisper_engine.rs:927
fs::remove_file(&model_info.path).await
.map_err(|e| anyhow!("Failed to delete file '{}': {}", model_info.path.display(), e))?;
log::info!("Successfully deleted available model file: {}", model_info.path.display());
} else {
log::warn!("File '{}' does not exist, nothing to delete", model_info.path.display());
}
// Update model status to Missing
{
let mut models = self.available_models.write().await;
if let Some(model) = models.get_mut(model_name) {
model.status = ModelStatus::Missing;
}
}
Ok(format!("Successfully deleted model '{}'", model_name))
}
_ => {
Err(anyhow!("Can only delete corrupted or available models. Model '{}' has status: {:?}", model_name, model_info.status))
}
}
}
async fn reserve_active_download(&self, model_name: &str) -> Result<Arc<ActiveDownload>> {
let mut active_downloads = self.active_downloads.lock().await;
if active_downloads.contains_key(model_name) {
return Err(anyhow!("Download already in progress for model: {}", model_name));
}
let (completion, _) = watch::channel(false);
let active_download = Arc::new(ActiveDownload {
cancellation: CancellationToken::new(),
completion,
});
active_downloads.insert(model_name.to_string(), Arc::clone(&active_download));
Ok(active_download)View on GitHub (pinned to a2cb62e827)