{"record":{"id":"90bf6216175a872c","repo":"janhq/jan","slug":"e-index","errorCode":null,"errorMessage":"e","messagePattern":"e","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"extensions/llamacpp-extension/src/index.ts","lineNumber":2573,"sourceCode":"      throw new Error(`Model ${modelId} does not exist`)\n    }\n\n    await fs.rm(modelDir)\n\n    try {\n      await this.refreshEnginePreset()\n    } catch (e) {\n      logger.warn(`Router refresh after delete(${modelId}) failed:`, e)\n    }\n  }\n\n  override async getLoadedModels(): Promise<string[]> {\n    try {\n      let models: string[] = await pluginGetLoadedModels()\n      return models\n    } catch (e) {\n      logger.error(e)\n      throw new Error(e)\n    }\n  }\n\n  /**\n   * Check if mmproj.gguf file exists for a given model ID\n   * @param modelId - The model ID to check for mmproj.gguf\n   * @returns Promise<boolean> - true if mmproj.gguf exists, false otherwise\n   */\n  async checkMmprojExists(modelId: string): Promise<boolean> {\n    try {\n      const modelConfigPath = await joinPath([\n        await this.getProviderPath(),\n        'models',\n        modelId,\n        'model.yml',\n      ])\n\n      const modelConfig = await invoke<ModelConfig>('read_yaml', {","sourceCodeStart":2555,"sourceCodeEnd":2591,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/extensions/llamacpp-extension/src/index.ts#L2555-L2591","documentation":"getLoadedModels catches any failure from pluginGetLoadedModels (querying the engine's loaded-model list), logs it, and rethrows it wrapped as new Error(e). Passing a non-string to the Error constructor produces 'e' as the message when e is an Error object, making the rethrown error nearly useless to callers.","triggerScenarios":"pluginGetLoadedModels rejects — engine subprocess not running/IPC failure, engine returning malformed data, or any internal plugin error while enumerating loaded models.","commonSituations":"llamacpp engine not started yet when the UI queries loaded models; engine crashed during a previous inference; IPC/tauri invoke failure between extension and engine.","solutions":["Check the logged original error (logger.error output) — the rethrown message 'e' is not informative.","Ensure the llamacpp engine/provider is started before calling getLoadedModels.","Restart the engine process if it crashed and retry.","Fix the wrapper to preserve the original message: use new Error(e instanceof Error ? e.message : String(e))."],"exampleFix":"// before\n} catch (e) {\n  logger.error(e)\n  throw new Error(e)\n}\n// after\n} catch (e) {\n  logger.error(e)\n  throw new Error(`getLoadedModels failed: ${e instanceof Error ? e.message : String(e)}`)\n}","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"function isWrappedPluginError(e: unknown): boolean {\n  return e instanceof Error && e.message === 'e'\n}","tryCatchPattern":"let loaded: string[] = []\ntry {\n  loaded = await getLoadedModels()\n} catch {\n  // engine may not be running yet; fall back to empty list and retry later\n  loaded = []\n}","preventionTips":["Start the llamacpp engine/provider before querying loaded models.","Retry with backoff — engine startup races produce this frequently.","Inspect logs for the real error since the rethrown message is uninformative ('e').","Patch the wrapper to rethrow e instanceof Error ? e : new Error(String(e))."],"tags":["error-wrapping","llamacpp","ipc"],"backgroundTag":"internal-invariant-violation","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"}