{"record":{"id":"babaa9ca2d7c8bb2","repo":"janhq/jan","slug":"model-modelid-already-exists","errorCode":null,"errorMessage":"Model ${modelId} already exists","messagePattern":"Model (.+?) already exists","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/llamacpp-extension/src/index.ts","lineNumber":3097,"sourceCode":"\n      // check for empty parts or path traversal\n      const parts = id.split('/')\n      return parts.every((s) => s !== '' && s !== '.' && s !== '..')\n    }\n\n    if (!isValidModelId(modelId))\n      throw new Error(\n        `Invalid modelId: ${modelId}. Only alphanumeric and / _ - . characters are allowed.`\n      )\n\n    const configPath = await joinPath([\n      await this.getProviderPath(),\n      'models',\n      modelId,\n      'model.yml',\n    ])\n    if (await fs.existsSync(configPath))\n      throw new Error(`Model ${modelId} already exists`)\n\n    // this is relative to Jan's data folder\n    const modelDir = `${this.providerId}/models/${modelId}`\n\n    // we only use these from opts\n    // opts.modelPath: URL to the model file\n    // opts.mmprojPath: URL to the mmproj file\n\n    let downloadItems: DownloadItem[] = []\n\n    const maybeDownload = async (path: string, saveName: string) => {\n      // if URL, add to downloadItems, and return local path\n      if (path.startsWith('https://')) {\n        const localPath = `${modelDir}/${saveName}`\n        downloadItems.push({\n          url: path,\n          save_path: localPath,\n          proxy: await getProxyConfig(),","sourceCodeStart":3079,"sourceCodeEnd":3115,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/extensions/llamacpp-extension/src/index.ts#L3079-L3115","documentation":"Thrown by runImport() when configPath (<provider>/models/<modelId>/model.yml) already exists. This is the duplicate-import guard: a model with that exact id was already imported (the yml is the canonical 'this model is installed' marker). It fires after the id-validity check but before any download, so no network work is wasted on a duplicate.","triggerScenarios":"Calling import('qwen7b', opts) when qwen7b is already in the models list. A prior import completed successfully and the user clicks import again. The model folder exists from a partial/cancelled prior import that still wrote model.yml. Two UI entries race but the in-flight dedupe (pendingImports) didn't catch them because they used different modelId strings that resolve to the same folder.","commonSituations":"Re-importing after a download error that was actually a validation failure but model.yml had already been written. User cleared the UI list but not the on-disk folder. Migration restored the models folder from backup so ids already exist.","solutions":["If you intend to re-import, delete the existing model first: await provider.delete(modelId).","Check for the model before importing via the model list / fs.existsSync(configPath) and skip or prompt.","Use a different modelId for the new import if both copies should coexist.","If model.yml is a stale leftover from a failed import, remove the model folder manually then retry."],"exampleFix":"// before\nawait provider.import('qwen7b', opts) // throws - already exists\n// after - re-import path\ntry {\n  await provider.import('qwen7b', opts)\n} catch (e) {\n  if (/already exists/.test(String(e))) { await provider.delete('qwen7b'); await provider.import('qwen7b', opts) }\n  else throw e\n}","handlingStrategy":"validation","validationCode":"// Check for an existing model.yml before importing\nconst cfg = await joinPath([await provider.getProviderPath(), 'models', modelId, 'model.yml'])\nif (await fs.existsSync(cfg)) {\n  // either skip, prompt to overwrite, or delete first\n  throw new Error(`'${modelId}' is already imported`)\n}","typeGuard":"async function isModelImported(provider: { getProviderPath(): Promise<string> }, id: string): Promise<boolean> {\n  const cfg = await joinPath([await provider.getProviderPath(), 'models', id, 'model.yml'])\n  return fs.existsSync(cfg)\n}","tryCatchPattern":"try { await provider.import(modelId, opts) }\ncatch (e) {\n  if (/already exists/.test(String(e))) { await provider.delete(modelId); await provider.import(modelId, opts) }\n  else throw e\n}","preventionTips":["Search the model list before offering import to dedupe in the UI.","On import failure, ensure model.yml is cleaned up so it isn't a false positive later.","Use unique ids (e.g. append a hash or date) if you import many variants."],"tags":["model","import","duplicate","filesystem","validation"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}