janhq/jan · critical · Error
MLX model has crashed! Please reload!
Error message
MLX model has crashed! Please reload!
What it means
Thrown by chat() when is_mlx_process_running returns false — the OS reports the MLX server process is gone, i.e. it crashed or was killed externally. Unlike error 50 (process alive but unresponsive), here the process is definitively dead. The session entry is now orphaned; the caller must reload.
Source
Thrown at extensions/mlx-extension/src/index.ts:378
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!')
}
const baseUrl = `http://localhost:${sessionInfo.port}/v1`
const url = `${baseUrl}/chat/completions`
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${sessionInfo.api_key}`,
}
const body = JSON.stringify(opts)
if (opts.stream) {
return this.handleStreamingResponse(url, headers, body, abortController)
}
const response = await fetch(url, {
method: 'POST',
headers,View on GitHub (pinned to fad3f12a14)
Solutions
- Reload the model with engine.load(opts.model) to spawn a fresh server.
- If it repeatedly crashes, use a smaller ctx_size or a smaller model that fits GPU memory.
- Free GPU/system memory before reloading (close other GPU apps).
- Check system logs for the OOM/segfault cause.
Example fix
// before
const completion = await engine.chat(opts)
// after
try {
return await engine.chat(opts)
} catch (e) {
if (/has crashed/.test(String(e))) {
await engine.unload(opts.model).catch(() => {})
await engine.load(opts.model)
return await engine.chat(opts)
}
throw e
} Defensive patterns
Strategy: fallback
Validate before calling
import { invoke } from '@tauri-apps/api/core'
async function isMlxAlive(pid: number): Promise<boolean> {
try { return await invoke<boolean>('plugin:mlx|is_mlx_process_running', { pid }) }
catch { return false }
}
if (!(await isMlxAlive(sessionInfo.pid))) {
await engine.load(opts.model) // respawn before chat
} Try / catch
try {
return await engine.chat(opts, abort)
} catch (e) {
if (/has crashed/.test(String(e))) {
await engine.unload(opts.model).catch(() => {})
await engine.load(opts.model)
return await engine.chat(opts, abort)
}
throw e
} Prevention
- Use a model/ctx_size that fits GPU memory to avoid OOM crashes.
- Free GPU resources before loading.
- Check is_mlx_process_running before chat if crashes are common.
When it happens
Trigger: MLX server segfaulted or was OOM-killed; user or another tool killed the pid; the process exited after a fatal Metal/runtime error; app resumed from sleep and the process did not survive.
Common situations: Out of memory on the GPU/system killed the server; a model too large for available memory crashed on first inference; system sleep/ resume orphaned the process; manual kill via Activity Monitor.
Related errors
- MLX model appears to have crashed! Please reload!
- No active MLX session found for model: ${opts.model}
- Model already loaded!
- No active MLX session found for model: ${modelId}
- MLX API request failed with status ${response.status}: ${JSO
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/fc7402d6012dc2a2.
Report an issue: GitHub.