{"record":{"id":"5530948fcdece88d","repo":"janhq/jan","slug":"no-running-mlx-session-found-for-model-modelid","errorCode":null,"errorMessage":"No running MLX session found for model: ${modelId}","messagePattern":"No running MLX session found for model: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web-app/src/lib/model-factory.ts","lineNumber":1022,"sourceCode":"        }\n      } catch (error) {\n        console.error('Failed to start MLX model:', error)\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:mlx|find_mlx_session_by_model',\n      { modelId }\n    )\n\n    if (!sessionInfo) {\n      throw new Error(`No running MLX session found for model: ${modelId}`)\n    }\n\n    const baseUrl = `http://localhost:${sessionInfo.port}`\n    const authHeaders = {\n      Authorization: `Bearer ${sessionInfo.api_key}`,\n      Origin: 'tauri://localhost',\n    }\n\n    // Share the common fetch (param normalisation + error-body cleaning that\n    // rebuilds upstream errors from buffered text rather than re-decoding the\n    // raw stream) with every other provider, then layer MLX's /cancel-on-abort\n    // on top.\n    let baseCustomFetch = createCustomFetch(\n      httpFetch,\n      parameters,\n      false,\n      undefined,\n      true","sourceCodeStart":1004,"sourceCodeEnd":1040,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/web-app/src/lib/model-factory.ts#L1004-L1040","documentation":"Thrown by createMlxModel when invoke('plugin:mlx|find_mlx_session_by_model', { modelId }) returns null after the start phase. Mirrors the llama.cpp noRunningSession case but, unlike [143], uses a hardcoded English string instead of an i18n key — an inconsistency to be aware of when localizing (model-factory.ts:1022).","triggerScenarios":"provider is falsy so the startModel block is skipped; startModel resolved but the MLX sidecar session was not registered or crashed between start and lookup; rapid model switching / page reload during boot; KILL_SIDECAR emitted mid-start.","commonSituations":"Switching away from the MLX model immediately after selecting it; MLX sidecar crashed on init but startModel's promise already resolved; modelId mismatch between start and lookup.","solutions":["Ensure provider is passed so startModel runs before the session lookup.","Avoid model swaps and page reloads during MLX boot.","Inspect the mlx extension logs for a crashed/unregistered session.","Align modelId between startModel and find_mlx_session_by_model."],"exampleFix":"// before\nif (!sessionInfo) {\n  throw new Error(`No running MLX session found for model: ${modelId}`)\n}\n// after: use the i18n key like the llama.cpp path for consistency\nif (!sessionInfo) {\n  throw new Error(i18n.t('model-errors:noRunningSession', { model: modelId }))\n}","handlingStrategy":"retry","validationCode":"function assertProviderForMlx(provider: ProviderObject | undefined, modelId: string) {\n  if (!provider) throw new Error(`Cannot start MLX ${modelId}: provider object is required`)\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:mlx|find_mlx_session_by_model', { modelId })\nif (!sessionInfo) {\n  await new Promise(r => setTimeout(r, 500))\n  sessionInfo = await invoke<SessionInfo | null>('plugin:mlx|find_mlx_session_by_model', { modelId })\n}\nif (!sessionInfo) throw new Error(i18n.t('model-errors:noRunningSession', { model: modelId }))","preventionTips":["Pass provider into createMlxModel so startModel actually runs.","Do not reload the page or swap models during MLX boot.","Align modelId between startModel and find_mlx_session_by_model.","Convert the hardcoded message to the i18n key for parity with the llama.cpp path."],"tags":["mlx","local-model","session","race-condition","tauri","i18n","typescript"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}