{"record":{"id":"7d87f476e128fc30","repo":"janhq/jan","slug":"failed-to-load-llamacpp-backend","errorCode":null,"errorMessage":"Failed to load llamacpp backend","messagePattern":"Failed to load llamacpp backend","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/llamacpp-extension/src/index.ts","lineNumber":4089,"sourceCode":"                        return { ...dev, mem: total, free }\n                      }\n                    }\n                  }\n                }\n                return dev\n              })\n              return adjusted\n            }\n          }\n        }\n      } catch (e) {\n        logger.warn('Device memory override (AMD/Linux) failed:', e)\n      }\n\n      return dList\n    } catch (error) {\n      logger.error('Failed to query devices:\\n', error)\n      throw new Error('Failed to load llamacpp backend')\n    }\n  }\n\n  /**\n   * Resolves the default/preferred embedding model, importing and loading\n   * sentence-transformer-mini as the fallback, then ensures a session exists.\n   * Shared by embed() and getEmbeddingContextSize() so both agree on which\n   * model is \"the\" embedding model.\n   */\n  private async ensureEmbeddingModelLoaded(): Promise<SessionInfo> {\n    const downloadedModelList = await this.list()\n    const installedEmbedding = downloadedModelList.filter(\n      (m) => (m as any).embedding === true\n    )\n    const hasMini = downloadedModelList.some(\n      (m) => m.id === FALLBACK_EMBEDDING_MODEL_ID\n    )\n    let preferred = await getDefaultEmbeddingModelId('llamacpp')","sourceCodeStart":4071,"sourceCodeEnd":4107,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/extensions/llamacpp-extension/src/index.ts#L4071-L4107","documentation":"Catch-all thrown by getDevices() when invoke('plugin:llamacpp|get_devices', ...) rejects. By this point version_backend parsed and ensureBackendReady() succeeded, so the backend binary exists; the failure is in executing it with --list-devices or in the Tauri plugin layer. The original error is logged but not surfaced.","triggerScenarios":"The backend executable is present but cannot run (wrong architecture, missing system libs like Vulkan/ROCm/CUDA runtime, exec permission bit unset); the --list-devices invocation crashes; the Tauri plugin command itself errors (serialization, permission scope).","commonSituations":"Missing GPU driver/runtime (Vulkan loader, CUDA toolkit, ROCm) on Linux; running an x86 backend on ARM or vice versa; a partially downloaded/corrupted backend binary; OS permission or sandbox blocking process spawn.","solutions":["Install the required GPU runtime for the selected backend (Vulkan loader, CUDA, or ROCm packages).","Re-download the backend via the app's backend management so the binary is not corrupt/truncated.","Run the backend binary manually with --list-devices from a terminal to see the real native error the plugin swallowed.","Switch the llamacpp backend variant to one matching your CPU arch / available GPU stack."],"exampleFix":"// before\nreturn await engine.getDevices()\n\n// after (surface native error for diagnosis)\ntry {\n  return await engine.getDevices()\n} catch (e) {\n  console.error('get_devices failed; run', backendPath, '--list-devices manually')\n  throw e\n}","handlingStrategy":"try-catch","validationCode":"import { getBackendExePath } from './backends'\nimport { fs } from '@janhub/core'\n\nasync function backendBinaryReady(backend: string, version: string): Promise<boolean> {\n  try {\n    const p = await getBackendExePath(backend, version)\n    return fs.existsSync(p)\n  } catch { return false }\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await engine.getDevices()\n} catch (e) {\n  if (/Failed to load llamacpp backend/.test(String(e))) {\n    // run the binary directly to capture the native error\n    logNativeError(backendPath, '--list-devices')\n  }\n  throw e\n}","preventionTips":["Install the GPU runtime (Vulkan/CUDA/ROCm) matching the selected backend.","Run the backend binary with --list-devices manually after install to confirm it works.","Re-download a corrupted backend rather than retrying blindly."],"tags":["backend","gpu-driver","native-binary","tauri","typescript"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}