{"record":{"id":"739f5f0253ce6eb3","repo":"janhq/jan","slug":"model-modelid-does-not-exist-739f5f","errorCode":null,"errorMessage":"Model ${modelId} does not exist","messagePattern":"Model (.+?) does not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extensions/mlx-extension/src/index.ts","lineNumber":542,"sourceCode":"            throw new Error(error.message)\n          }\n        }\n      }\n    } finally {\n      reader.releaseLock()\n    }\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    const modelConfigPath = await joinPath([modelDir, 'model.yml'])\n    if (!(await fs.existsSync(modelConfigPath))) {\n      throw new Error(`Model ${modelId} does not exist`)\n    }\n\n    const modelConfig = await invoke<ModelConfig>('read_yaml', {\n      path: modelConfigPath,\n    })\n\n    // Check if model_path is a relative path within mlx folder\n    if (!isAbsoluteModelPath(modelConfig.model_path)) {\n      // Model file is at {janDataFolder}/{model_path}\n      // Delete the parent folder containing the actual model file\n      const janDataFolderPath = await getJanDataFolderPath()\n      const modelPath = await joinPath([\n        janDataFolderPath,\n        modelConfig.model_path,\n      ])\n      const parentDir = modelPath.substring(0, modelPath.lastIndexOf('/'))\n      // Only delete if it's different from modelDir (i.e., not the same folder)\n      if (parentDir !== modelDir) {","sourceCodeStart":524,"sourceCodeEnd":560,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/extensions/mlx-extension/src/index.ts#L524-L560","documentation":"The delete() method builds the model directory path under the provider's models folder and requires a model.yml inside it; if that file is missing, it concludes no model with the given modelId exists and throws. It guards against deleting non-existent or corrupted model folders.","triggerScenarios":"Calling delete(modelId) where <providerPath>/models/<modelId>/model.yml does not exist — wrong ID, model never imported, folder deleted manually, or the folder exists but model.yml was removed.","commonSituations":"Typos in model ID, deleting a model twice (second call fails), models created by older extension versions with a different layout, users cleaning the models directory by hand.","solutions":["List installed models first and confirm the exact modelId before deleting","Re-download/import the model if its model.yml is missing","Guard the delete call with an existence check on the model list","Correct the model ID spelling/case"],"exampleFix":"// before\nawait mlx.delete('my-model')\n// after\nconst models = await mlx.getModels()\nif (models.some(m => m.id === 'my-model')) {\n  await mlx.delete('my-model')\n}","handlingStrategy":"validation","validationCode":"const models = await mlx.getModels()\nconst exists = models.some(m => m.id === modelId)\nif (!exists) return // nothing to delete\nawait mlx.delete(modelId)","typeGuard":"const modelExists = (models, id) => Array.isArray(models) && models.some(m => m?.id === id)","tryCatchPattern":"try {\n  await mlx.delete(modelId)\n} catch (e) {\n  if (String(e.message).includes('does not exist')) return // already gone: treat as idempotent\n  throw e\n}","preventionTips":["Always resolve model IDs from a listing call, never from user-typed strings","Make delete idempotent by catching not-found","Don't hand-edit or prune files inside the provider's models directory","Treat double-delete attempts as no-ops in app logic"],"tags":["mlx","not-found","file-not-found","model-management"],"backgroundTag":"file-not-found","analyzedSha":"7205d770c1e097c3daf35a911176410e93bc5564","analyzedAt":"2026-09-17T14:27:30.100Z","contentChangedAt":"2026-09-17T14:27:30.100Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}