{"record":{"id":"fe53391a59e47dca","repo":"janhq/jan","slug":"model-already-loaded","errorCode":null,"errorMessage":"Model already loaded!!","messagePattern":"Model already loaded!!","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extensions/llamacpp-extension/src/index.ts","lineNumber":2258,"sourceCode":"\n        if (\n          cleanKey &&\n          valueParts.length > 0 &&\n          !cleanKey.startsWith('LLAMA')\n        ) {\n          target[cleanKey] = valueParts.join('=').trim()\n        }\n      })\n  }\n\n  override async load(\n    modelId: string,\n    _settings?: unknown,\n    isEmbedding: boolean = false\n  ): Promise<SessionInfo> {\n    const sInfo = await this.findSessionByModel(modelId)\n    if (sInfo) {\n      throw new Error('Model already loaded!!')\n    }\n\n    if (this.loadingModels.has(modelId)) {\n      return this.loadingModels.get(modelId)!\n    }\n\n    const loadingPromise = this.performLoad(modelId, isEmbedding)\n    this.loadingModels.set(modelId, loadingPromise)\n\n    try {\n      return await loadingPromise\n    } finally {\n      this.loadingModels.delete(modelId)\n    }\n  }\n\n  // Awaits the deferred startup, then makes one direct attempt if the worker\n  // still isn't up. Safe to call redundantly: start_engine returns the running","sourceCodeStart":2240,"sourceCodeEnd":2276,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/extensions/llamacpp-extension/src/index.ts#L2240-L2276","documentation":"load() first checks findSessionByModel(modelId); if a live session for that model already exists it throws 'Model already loaded!!'. Loading the same model twice is not permitted — the extension manages one session per model, and loadModelId checks come before the concurrent-load dedup via loadingModels map.","triggerScenarios":"Calling load() (or the public loadModel path) twice for the same modelId without unloading in between; UI double-clicking the load button; a retry loop after a slow load that actually succeeded.","commonSituations":"Race between user action and an automatic preload; re-running a script that loads models without unloading; a previous load completed but the caller assumed it failed.","solutions":["Check findSessionByModel / session state and reuse the existing sessionInfo instead of loading again","Call unload(modelId) before loading if you need a fresh load","Serialize load requests in your UI so a second click is ignored while loading","Wrap the load in a guard: if already loaded, return the existing session"],"exampleFix":"// before\nconst s = await load(modelId) // may double-load\n// after\nlet s = await findSessionByModel(modelId)\nif (!s) s = await load(modelId)","handlingStrategy":"try-catch","validationCode":"const existing = await findSessionByModel(modelId)\nif (existing) return existing // already loaded; reuse","typeGuard":null,"tryCatchPattern":"try {\n  return await load(modelId)\n} catch (e) {\n  if (e.message === 'Model already loaded!!') return await findSessionByModel(modelId)\n  throw e\n}","preventionTips":["Track loaded models in your own state map","Disable load buttons while a load is in flight","Unload before reloading when a fresh session is required","Handle retries idempotently — check session first"],"tags":["duplicate-load","state-conflict","session"],"backgroundTag":"invalid-state-transition","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"}