{"record":{"id":"babaa9ca2d7c8bb2","repo":"janhq/jan","slug":"model-modelid-already-exists","errorCode":null,"errorMessage":"Model ${modelId} already exists","messagePattern":"Model (.+?) already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extensions/llamacpp-extension/src/index.ts","lineNumber":1899,"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":1881,"sourceCodeEnd":1917,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/extensions/llamacpp-extension/src/index.ts#L1881-L1917","documentation":"The model-creation flow writes model.yml at <providerPath>/models/<modelId>/model.yml. If a config file for that modelId already exists, the extension throws this error instead of silently overwriting an existing registered model.","triggerScenarios":"Calling the register/add-model method with a modelId whose model.yml already exists on disk under the provider's models directory.","commonSituations":"Adding the same model twice; retrying a registration that partially succeeded; importing a model that duplicates an existing ID; leftover configs after manual deletion of weights but not configs.","solutions":["Pick a unique modelId not already present in the models directory","Delete the existing <providerPath>/models/<modelId>/model.yml if that model is obsolete","List existing models first and skip/dedupe before registering","Remove the whole stale model directory if it is a leftover partial import"],"exampleFix":"// before\nawait addModel({ modelId: 'qwen2-7b', ... }) // second call with same id\n// after\nif (!(await modelExists('qwen2-7b'))) await addModel({ modelId: 'qwen2-7b', ... })","handlingStrategy":"validation","validationCode":"const configPath = await joinPath([providerPath, 'models', modelId, 'model.yml'])\nif (await fs.existsSync(configPath)) return // skip; already registered","typeGuard":null,"tryCatchPattern":"try {\n  await addModel({ modelId, ...opts })\n} catch (e) {\n  if (e.message === `Model ${modelId} already exists`) return existingModel\n  throw e\n}","preventionTips":["Check existence before registering (idempotent add)","Dedupe by modelId in your sync/import code","Delete obsolete model.yml configs when re-registering","Keep a local registry of registered IDs"],"tags":["file-conflict","duplicate","model-registration"],"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"}