janhq/jan · error · Error

No active MLX session found for model: ${opts.model}

Error message

No active MLX session found for model: ${opts.model}

What it means

Thrown by chat() at its very start when findSessionByModel(opts.model) returns no session. The chat request names a model (opts.model) that has no running MLX server, so inference cannot be routed. This mirrors error 48 but on the chat path and uses opts.model rather than a bare modelId.

Source

Thrown at extensions/mlx-extension/src/index.ts:362

  private async findSessionByModel(modelId: string): Promise<SessionInfo> {
    try {
      return await invoke<SessionInfo>('plugin:mlx|find_mlx_session_by_model', {
        modelId,
      })
    } catch (e) {
      logger.error(e)
      throw new Error(String(e))
    }
  }

  override async chat(
    opts: chatCompletionRequest,
    abortController?: AbortController
  ): Promise<chatCompletion | AsyncIterable<chatCompletionChunk>> {
    const sessionInfo = await this.findSessionByModel(opts.model)
    if (!sessionInfo) {
      throw new Error(`No active MLX session found for model: ${opts.model}`)
    }

    // Check if the process is alive
    const isAlive = await invoke<boolean>('plugin:mlx|is_mlx_process_running', {
      pid: sessionInfo.pid,
    })

    if (isAlive) {
      try {
        await fetch(`http://localhost:${sessionInfo.port}/health`)
      } catch (e) {
        this.unload(sessionInfo.model_id)
        throw new Error('MLX model appears to have crashed! Please reload!')
      }
    } else {
      throw new Error('MLX model has crashed! Please reload!')
    }

View on GitHub (pinned to fad3f12a14)

Solutions

  1. Call engine.load(opts.model) before issuing chat, or ensure the model is in getLoadedModels().
  2. If autoUnload is enabled, reload the requested model when the user switches back to it.
  3. Normalize opts.model to the canonical model id used at import time.

Example fix

// before
const result = await engine.chat(opts, abort)

// after
if (!(await engine.findSessionByModel(opts.model).catch(() => null))) {
  await engine.load(opts.model)
}
const result = await engine.chat(opts, abort)
Defensive patterns

Strategy: validation

Validate before calling

if (!(await engine.findSessionByModel(opts.model).catch(() => null))) {
  await engine.load(opts.model)
}
await engine.chat(opts, abort)

Try / catch

try {
  return await engine.chat(opts, abort)
} catch (e) {
  if (/No active MLX session/.test(String(e))) {
    await engine.load(opts.model)
    return await engine.chat(opts, abort)
  }
  throw e
}

Prevention

When it happens

Trigger: Sending a chatCompletionRequest whose model field is an unloaded/never-loaded model; the session was auto-unloaded by autoUnload when another model loaded; the model crashed and its session was purged before chat() ran.

Common situations: UI sends a message for a model the user switched away from (autoUnload cleared it); opts.model is a display name or stale id; crash left no session.

Related errors


AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12). Data as JSON: /api/errors/ca0bd35c49debb9a. Report an issue: GitHub.