{"record":{"id":"df18198f414f34cf","repo":"janhq/jan","slug":"model-errors-norunningsession","errorCode":"model-errors:noRunningSession","errorMessage":"model-errors:noRunningSession","messagePattern":"model-errors:noRunningSession","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web-app/src/lib/model-factory.ts","lineNumber":935,"sourceCode":"        console.error('Failed to start llamacpp model:', error)\n        // A serialized engine error is a plain object, so the previous\n        // `instanceof Error` path stringified it into raw JSON for the user.\n        throw new Error(\n          i18n.t('model-errors:startModelFailed', {\n            reason: describeEngineError(error),\n          })\n        )\n      }\n    }\n\n    // Get session info which includes port and api_key\n    const sessionInfo = await invoke<SessionInfo | null>(\n      'plugin:llamacpp|find_session_by_model',\n      { modelId }\n    )\n\n    if (!sessionInfo) {\n      throw new Error(\n        i18n.t('model-errors:noRunningSession', { model: modelId })\n      )\n    }\n\n    const onLlamacppServerError = provider\n      ? () => {\n          void (async () => {\n            try {\n              const { useServiceStore } = await import('@/hooks/useServiceHub')\n              const hub = useServiceStore.getState().serviceHub\n              await hub?.models().reloadModel(provider, modelId)\n            } catch (e) {\n              console.warn('[llamacpp] reload after crash failed:', e)\n            }\n          })()\n        }\n      : undefined\n    // The global toggle can strip reasoning_content from resent assistant turns,","sourceCodeStart":917,"sourceCodeEnd":953,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/web-app/src/lib/model-factory.ts#L917-L953","documentation":"Thrown by createLlamaCppModel when the Tauri invoke('plugin:llamacpp|find_session_by_model', { modelId }) returns null after the start phase. The model either was never started (provider was undefined so start was skipped) or started but no session registered for that modelId (model-factory.ts:935). Message is i18n key 'model-errors:noRunningSession'.","triggerScenarios":"provider is falsy so the startModel block is skipped entirely; startModel resolved but the sidecar crashed between start and find_session_by_model; a different modelId string is used for the lookup than was used for start (id drift); the session table was cleared (KILL_SIDECAR event) mid-flight.","commonSituations":"Reloading the page or cancelling inference right as the model boots; switching models rapidly so the prior session is torn down; the sidecar was killed by a data-folder relocation or settings change; modelId includes a provider prefix in one call but not the other.","solutions":["Ensure provider is passed into createLlamaCppModel so startModel actually runs.","Avoid concurrent model swaps / page reloads during boot; let startModel settle before issuing inference.","If reproducible, check the llama.cpp extension logs for a crashed or never-registered session.","Verify the modelId used for find_session_by_model matches the one startModel registered (no prefix/suffix drift)."],"exampleFix":"// before\nif (!sessionInfo) {\n  throw new Error(i18n.t('model-errors:noRunningSession', { model: modelId }))\n}\n// after: retry the lookup once after a short delay to absorb start/register race\nif (!sessionInfo) {\n  await new Promise(r => setTimeout(r, 500))\n  const retried = await invoke<SessionInfo | null>('plugin:llamacpp|find_session_by_model', { modelId })\n  if (!retried) throw new Error(i18n.t('model-errors:noRunningSession', { model: modelId }))\n  return buildLlamaCppModel(modelId, retried, ...)\n}","handlingStrategy":"retry","validationCode":"// ensure provider is passed so the start block runs\nfunction assertProviderForLocal(provider: ProviderObject | undefined, modelId: string) {\n  if (!provider) throw new Error(`Cannot start ${modelId}: provider object is required to boot a local session`)\n}","typeGuard":"function isSessionInfo(x: unknown): x is SessionInfo {\n  return typeof x === 'object' && x !== null && typeof (x as SessionInfo).port === 'number'\n}","tryCatchPattern":"let sessionInfo = await invoke<SessionInfo | null>('plugin:llamacpp|find_session_by_model', { modelId })\nif (!sessionInfo) {\n  // one bounded retry to absorb the start/register race\n  await new Promise(r => setTimeout(r, 500))\n  sessionInfo = await invoke<SessionInfo | null>('plugin:llamacpp|find_session_by_model', { modelId })\n}\nif (!sessionInfo) throw new Error(i18n.t('model-errors:noRunningSession', { model: modelId }))","preventionTips":["Always pass the provider object into createLlamaCppModel so startModel runs.","Avoid page reloads and rapid model swaps during boot.","Keep modelId identical between startModel and find_session_by_model (no prefix drift).","Listen for KILL_SIDECAR and abort in-flight session lookups instead of letting them return null."],"tags":["llamacpp","local-model","session","race-condition","tauri","typescript","i18n"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}