{"record":{"id":"d53078848ec99dc0","repo":"janhq/jan","slug":"model-modelid-does-not-exist","errorCode":null,"errorMessage":"Model ${modelId} does not exist","messagePattern":"Model (.+?) does not exist","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/llamacpp-extension/src/index.ts","lineNumber":3796,"sourceCode":"          errorData\n        )}`\n      )\n    }\n\n    const completionResponse = (await response.json()) as chatCompletion\n\n    return completionResponse\n  }\n\n  override async delete(modelId: string): Promise<void> {\n    const modelDir = await joinPath([\n      await this.getProviderPath(),\n      'models',\n      modelId,\n    ])\n\n    if (!(await fs.existsSync(await joinPath([modelDir, 'model.yml'])))) {\n      throw new Error(`Model ${modelId} does not exist`)\n    }\n\n    await fs.rm(modelDir)\n\n    try {\n      await this.refreshRouterPreset()\n    } catch (e) {\n      logger.warn(`Router refresh after delete(${modelId}) failed:`, e)\n    }\n  }\n\n  override async getLoadedModels(): Promise<string[]> {\n    try {\n      let models: string[] = await invoke<string[]>(\n        'plugin:llamacpp|get_loaded_models'\n      )\n      return models\n    } catch (e) {","sourceCodeStart":3778,"sourceCodeEnd":3814,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/extensions/llamacpp-extension/src/index.ts#L3778-L3814","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nawait provider.delete('qwen') // throws if already gone\n// after\ntry { await provider.delete('qwen') }\ncatch (e) { if (!/does not exist/.test(String(e))) throw e; /* already gone - fine */ }\n// or pre-check:\nconst yml = await joinPath([await provider.getProviderPath(), 'models', 'qwen', 'model.yml'])\nif (await fs.existsSync(yml)) await provider.delete('qwen')","handlingStrategy":"validation","validationCode":"// Confirm model.yml exists before calling delete\nconst yml = await joinPath([await provider.getProviderPath(), 'models', modelId, 'model.yml'])\nif (!(await fs.existsSync(yml))) {\n  // already gone, or never imported - treat as no-op\n  return\n}\nawait provider.delete(modelId)","typeGuard":"async function modelIsInstalled(provider: { getProviderPath(): Promise<string> }, id: string): Promise<boolean> {\n  const yml = await joinPath([await provider.getProviderPath(), 'models', id, 'model.yml'])\n  return fs.existsSync(yml)\n}","tryCatchPattern":"try { await provider.delete(modelId) }\ncatch (e) {\n  if (/does not exist/.test(String(e))) return // already gone - fine\n  throw e\n}","preventionTips":["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."],"tags":["model","delete","filesystem","validation","state"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}