{"record":{"id":"712b960a0e3e2f74","repo":"janhq/jan","slug":"llamacpp-extension-not-found","errorCode":null,"errorMessage":"LlamaCpp extension not found","messagePattern":"LlamaCpp extension not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web-app/src/hooks/useBackendUpdater.ts","lineNumber":312,"sourceCode":"\n      // Get llamacpp extension instance\n      const allExtensions = ExtensionManager.getInstance().listExtensions()\n      const llamacppExtension =\n        ExtensionManager.getInstance().getByName('llamacpp-extension')\n\n      let extensionToUse = llamacppExtension\n\n      if (!llamacppExtension) {\n        // Try to find by type or other properties\n        const possibleExtension = allExtensions.find(\n          (ext) =>\n            ext.constructor.name.toLowerCase().includes('llamacpp') ||\n            (ext.type &&\n              ext.type()?.toString().toLowerCase().includes('inference'))\n        )\n\n        if (!possibleExtension) {\n          throw new Error('LlamaCpp extension not found')\n        }\n\n        extensionToUse = possibleExtension\n      }\n\n      if (\n        !extensionToUse ||\n        !('getSettings' in extensionToUse) ||\n        !('updateBackend' in extensionToUse)\n      ) {\n        throw new Error('Extension does not support backend updates')\n      }\n\n      const extension = extensionToUse as LlamacppExtension\n\n      // Use the exact target backend from checkBackendForUpdates if available,\n      // to avoid mismatches between old/new backend name formats\n      let targetBackendString = updateState.updateInfo.targetBackend","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/web-app/src/hooks/useBackendUpdater.ts#L294-L330","documentation":"Thrown in the `updateBackend` path when `ExtensionManager.getByName('llamacpp-extension')` returns null AND no extension in `listExtensions()` matches by constructor-name containing 'llamacpp' or type-string containing 'inference'. The llamacpp extension is the only provider of backend-update capability, so its absence blocks the whole flow.","triggerScenarios":"The llamacpp extension is not installed, not registered under the expected name 'llamacpp-extension', and its constructor/type strings changed so the fuzzy fallback fails. Common after an app upgrade that renamed the extension or changed its registered name.","commonSituations":"Extension renamed in a new build (e.g. 'llamacpp' vs 'llamacpp-extension'); extension disabled/uninstalled; ExtensionManager not yet populated at the time of the call (timing/init race).","solutions":["Confirm the llamacpp extension is installed and enabled in Settings > Extensions.","Restart the app so extensions re-register.","Check the extension's registered name matches 'llamacpp-extension' (or update the fallback matcher).","Ensure ExtensionManager initialization completed before invoking updateBackend."],"exampleFix":"// before\nconst llamacppExtension = ExtensionManager.getInstance().getByName('llamacpp-extension')\nif (!llamacppExtension) {\n  const possibleExtension = allExtensions.find((ext) =>\n    ext.constructor.name.toLowerCase().includes('llamacpp') ||\n    (ext.type && ext.type()?.toString().toLowerCase().includes('inference'))\n  )\n  if (!possibleExtension) {\n    throw new Error('LlamaCpp extension not found')\n  }\n}\n\n// after\nconst llamacppExtension = ExtensionManager.getInstance().getByName('llamacpp-extension')\nif (!llamacppExtension) {\n  const possibleExtension = allExtensions.find((ext) =>\n    ext.constructor.name.toLowerCase().includes('llamacpp') ||\n    (ext.type && ext.type()?.toString().toLowerCase().includes('inference'))\n  )\n  if (!possibleExtension) {\n    throw new Error(\n      'LlamaCpp extension not found. Install/enable it in Settings > Extensions and restart.'\n    )\n  }\n}","handlingStrategy":"type-guard","validationCode":"const ext = ExtensionManager.getInstance().getByName('llamacpp-extension')\nif (!ext) {\n  toast.error('LlamaCpp extension missing', { description: 'Enable it in Settings > Extensions and restart.' })\n  return\n}","typeGuard":"function isLlamacppExtension(ext: unknown): ext is LlamacppExtension {\n  return !!ext && typeof (ext as any).getSettings === 'function'\n}","tryCatchPattern":"try {\n  const ext = ExtensionManager.getInstance().getByName('llamacpp-extension')\n  if (!isLlamacppExtension(ext)) {\n    toast.error('LlamaCpp extension not found', { description: 'Install/enable it and restart.' })\n    return\n  }\n  // proceed\n} catch (error) {\n  console.error('updateBackend:', error)\n  throw error\n}","preventionTips":["Ensure extensions finish registering before invoking update flows.","Keep the registered name stable across versions or update the lookup.","Disable shadowing extensions whose names match the fuzzy fallback."],"tags":["llamacpp","extension","backend","update"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}