{"record":{"id":"9132b8c393007fc9","repo":"janhq/jan","slug":"model-with-id-model-id-already-exists-9132b8","errorCode":null,"errorMessage":"Model with ID ${model.id} already exists","messagePattern":"Model with ID (.+?) already exists","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/mlx-extension/src/index.ts","lineNumber":588,"sourceCode":"    modelId: string,\n    model: Partial<modelInfo>\n  ): Promise<void> {\n    // Delegate to the same logic as llamacpp since they share the model dir\n    const modelFolderPath = await joinPath([\n      await this.getProviderPath(),\n      'models',\n      modelId,\n    ])\n    const modelConfig = await invoke<ModelConfig>('read_yaml', {\n      path: await joinPath([modelFolderPath, 'model.yml']),\n    })\n    const newFolderPath = await joinPath([\n      await this.getProviderPath(),\n      'models',\n      model.id,\n    ])\n    if (await fs.existsSync(newFolderPath)) {\n      throw new Error(`Model with ID ${model.id} already exists`)\n    }\n    const newModelConfigPath = await joinPath([newFolderPath, 'model.yml'])\n    await fs.mv(modelFolderPath, newFolderPath).then(() =>\n      invoke('write_yaml', {\n        data: {\n          ...modelConfig,\n          model_path: modelConfig?.model_path?.replace(\n            `mlx/models/${modelId}`,\n            `mlx/models/${model.id}`\n          ),\n        },\n        savePath: newModelConfigPath,\n      })\n    )\n  }\n\n  override async import(modelId: string, opts: ImportOptions): Promise<void> {\n    if (!isValidModelId(modelId))","sourceCodeStart":570,"sourceCodeEnd":606,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/extensions/mlx-extension/src/index.ts#L570-L606","documentation":"When adding/importing a model, the extension moves the model folder to <providerPath>/models/<model.id> and refuses to overwrite an existing directory, throwing this error if the target already exists. It prevents clobbering an installed model with the same ID.","triggerScenarios":"Importing a model whose id collides with an already-installed model's directory — re-importing the same model, two models configured with identical IDs, or leftover folders from a previous failed install.","commonSituations":"Duplicate imports after a partial failure left the folder behind, users importing a model twice, ID case-sensitivity confusion, importing another model that happens to use the same ID string.","solutions":["Delete the existing model with that ID first (via the delete API), then re-import","Use a unique model.id for the new import","Remove leftover model directories from previous failed installs","List installed models to check for ID collisions before importing"],"exampleFix":"// before\nawait mlx.importModel({ id: 'llama-3', folder })\n// after\nconst models = await mlx.getModels()\nif (!models.some(m => m.id === 'llama-3')) {\n  await mlx.importModel({ id: 'llama-3', folder })\n} else {\n  await mlx.delete('llama-3')\n  await mlx.importModel({ id: 'llama-3', folder })\n}","handlingStrategy":"validation","validationCode":"const models = await mlx.getModels()\nif (models.some(m => m.id === newModel.id)) {\n  await mlx.delete(newModel.id) // or pick a unique id\n}\nawait mlx.importModel(newModel)","typeGuard":"const idIsFree = async (id) => !(await mlx.getModels()).some(m => m.id === id)","tryCatchPattern":"try {\n  await mlx.importModel(model)\n} catch (e) {\n  if (String(e.message).includes('already exists')) {\n    await mlx.delete(model.id)\n    return mlx.importModel(model)\n  }\n  throw e\n}","preventionTips":["Check the installed-model list for ID collisions before every import","Clean up leftover folders after failed imports","Generate unique IDs (suffix with timestamp) for repeated imports","Never reuse an existing model's ID unless you intend replacement"],"tags":["mlx","duplicate","file-already-exists","model-management"],"backgroundTag":"file-already-exists","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"}