janhq/jan · error · Error
Model ${modelId} does not exist
Error message
Model ${modelId} does not exist What it means
Thrown by delete() when <provider>/models/<modelId>/model.yml does not exist. model.yml is the canonical 'this model is installed' marker; absence means the model was never imported, was already deleted, or its folder is corrupted (only partial files remain). delete refuses to proceed (and notably does NOT call fs.rm) to avoid silently removing an unrelated directory.
Source
Thrown at extensions/llamacpp-extension/src/index.ts:3796
errorData
)}`
)
}
const completionResponse = (await response.json()) as chatCompletion
return completionResponse
}
override async delete(modelId: string): Promise<void> {
const modelDir = await joinPath([
await this.getProviderPath(),
'models',
modelId,
])
if (!(await fs.existsSync(await joinPath([modelDir, 'model.yml'])))) {
throw new Error(`Model ${modelId} does not exist`)
}
await fs.rm(modelDir)
try {
await this.refreshRouterPreset()
} catch (e) {
logger.warn(`Router refresh after delete(${modelId}) failed:`, e)
}
}
override async getLoadedModels(): Promise<string[]> {
try {
let models: string[] = await invoke<string[]>(
'plugin:llamacpp|get_loaded_models'
)
return models
} catch (e) {View on GitHub (pinned to fad3f12a14)
Solutions
- Refresh the model list before offering delete; if the id is gone, drop it from the UI.
- Treat 'does not exist' as success if your goal is simply 'ensure the model is gone'.
- Verify the modelId matches the id shown at import time (case, slashes).
- If model.yml is missing but the folder has weight files, manually remove the orphan folder.
Example fix
// before
await provider.delete('qwen') // throws if already gone
// after
try { await provider.delete('qwen') }
catch (e) { if (!/does not exist/.test(String(e))) throw e; /* already gone - fine */ }
// or pre-check:
const yml = await joinPath([await provider.getProviderPath(), 'models', 'qwen', 'model.yml'])
if (await fs.existsSync(yml)) await provider.delete('qwen') Defensive patterns
Strategy: validation
Validate before calling
// Confirm model.yml exists before calling delete
const yml = await joinPath([await provider.getProviderPath(), 'models', modelId, 'model.yml'])
if (!(await fs.existsSync(yml))) {
// already gone, or never imported - treat as no-op
return
}
await provider.delete(modelId) Type guard
async function modelIsInstalled(provider: { getProviderPath(): Promise<string> }, id: string): Promise<boolean> {
const yml = await joinPath([await provider.getProviderPath(), 'models', id, 'model.yml'])
return fs.existsSync(yml)
} Try / catch
try { await provider.delete(modelId) }
catch (e) {
if (/does not exist/.test(String(e))) return // already gone - fine
throw e
} Prevention
- Refresh the model list from disk before offering delete in the UI.
- Make delete idempotent at the caller (treat 'does not exist' as success).
- Verify modelId casing/spelling against the imported id.
When it happens
Trigger: Calling delete on an id that was never imported; double-delete (UI fired the action twice); model folder partially cleaned by a previous failed delete leaving no model.yml; user hand-deleted model.yml but left the folder; wrong id (typo/case).
Common situations: UI list is stale and shows a model already removed from disk. Migrating between data folders leaves dangling list entries. User clicks delete twice quickly. Case-insensitive FS id mismatch.
Related errors
- Model with ID ${model.id} already exists
- Model ${modelId} already exists
- File not found: ${path}
- No active session found for model: ${modelId}
- model.yml not found for ${modelId}
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/d53078848ec99dc0.
Report an issue: GitHub.