{"record":{"id":"b1a7fe77623da9fe","repo":"janhq/jan","slug":"llama-cpp-router-is-not-running-please-restart-th","errorCode":null,"errorMessage":"llama.cpp router is not running. Please restart the app.","messagePattern":"llama\\.cpp router is not running\\. Please restart the app\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"extensions/llamacpp-extension/src/index.ts","lineNumber":3468,"sourceCode":"  // still isn't up. Safe to call redundantly: startRouter reuses a router that\n  // already matches this config rather than respawning it.\n  private async ensureRouterReady(): Promise<void> {\n    // Provisions if the setup screen never got the chance to ask, so skipping\n    // setup and later loading a local model still works.\n    await this.ensureProvisioned().catch(() => undefined)\n    if (!(await this.getRouterInfo())) {\n      await this.startRouter()\n    }\n  }\n\n  private async performLoad(\n    modelId: string,\n    isEmbedding: boolean = false\n  ): Promise<SessionInfo> {\n    await this.ensureRouterReady()\n    const router = await this.getRouterInfo()\n    if (!router) {\n      throw new Error(\n        'llama.cpp router is not running. Please restart the app.'\n      )\n    }\n\n    if (!isEmbedding) {\n      await this.evictChatIfAtCapacity(modelId)\n    }\n\n    try {\n      const info = await loadLlamaModel(modelId, isEmbedding)\n      if (!isEmbedding) {\n        this.loadedChatOrder = this.loadedChatOrder.filter((m) => m !== modelId)\n        this.loadedChatOrder.push(modelId)\n      }\n      return info\n    } catch (error) {\n      logger.error('Error in load command:\\n', error)\n      throw error","sourceCodeStart":3450,"sourceCodeEnd":3486,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/extensions/llamacpp-extension/src/index.ts#L3450-L3486","documentation":"Thrown by performLoad() after ensureRouterReady() (which itself tries ensureProvisioned + getRouterInfo, then startRouter if down) and a second getRouterInfo() still returns null. The llama.cpp router is the sidecar process that owns model sessions; without it, loadLlamaModel cannot be issued. This error means the router failed to start or crashed during startup and could not be recovered.","triggerScenarios":"Router binary is missing, not executable, or the wrong arch (e.g. arm binary on x86). Router crashed on startup due to a port conflict (getRandomPort range collision), missing system libs, or a malformed config. Provisioning/install never completed so the binary isn't on disk. A security tool blocked the router process. Antivirus quarantined llama-server.","commonSituations":"First run after install where backend provisioning silently failed. OS update removed a runtime dependency (libc, Vulkan loader). Another app holds the ephemeral port the router picked. Corporate endpoint protection blocks the unsigned sidecar. User moved the data folder and the relative path to the router binary no longer resolves.","solutions":["Restart the app as the message suggests - a transient router crash on startup often recovers on relaunch.","Re-provision the backend (installBackend) to ensure the matching llama-server binary exists and is executable.","Check the logs for the router's stderr - look for missing libs, port-in-use, or permission errors and address the specific cause.","Free up the port range or kill orphaned llama-server processes left by a previous crash.","On Linux, install missing dynamic loader deps (ldd on the binary); on Windows, install the VC++ redistributable / CUDA runtime."],"exampleFix":"// before\nawait provider.load('qwen') // throws: router not running\n// after\nlet info = await provider.getRouterInfo()\nif (!info) {\n  await provider.ensureProvisioned()\n  await provider.startRouter()\n  info = await provider.getRouterInfo()\n}\nif (!info) throw new Error('router still down - check logs for root cause')\nawait provider.load('qwen')","handlingStrategy":"retry","validationCode":"// Best-effort router liveness check with explicit retry before failing\nasync function ensureRouterUp(provider: any, retries = 3) {\n  for (let i = 0; i < retries; i++) {\n    if (await provider.getRouterInfo()) return\n    await provider.ensureProvisioned().catch(() => {})\n    await provider.startRouter()\n  }\n  throw new Error('router could not be started after retries - inspect logs')\n}","typeGuard":"async function routerIsAlive(provider: { getRouterInfo(): Promise<unknown> }): Promise<boolean> {\n  try { return Boolean(await provider.getRouterInfo()) } catch { return false }\n}","tryCatchPattern":"try { await provider.load(modelId) }\ncatch (e) {\n  if (/router is not running/.test(String(e))) { await restartAppOrRouter(); await provider.load(modelId) }\n  else throw e\n}","preventionTips":["Run backend provisioning to completion before exposing model load.","Detect router crashes at startup and surface the router's stderr to the user.","Ensure no other process holds the router's port range; clean up orphan llama-server processes."],"tags":["router","load","startup","sidecar","process","critical"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}