janhq/jan · error
MLX model appears to have crashed! Please reload!
Error message
MLX model appears to have crashed! Please reload!
What it means
The jan extension's chat() checks whether the local MLX server subprocess is still alive and responsive by hitting its /health endpoint. When the process is alive but the health fetch rejects (connection refused, timeout, reset socket), the model session is unloaded and this error is thrown, telling the user to reload the model.
Solutions
- Reload the model (unload then load again) to spawn a fresh MLX server session
- Check that no HTTP_PROXY/HTTPS_PROXY env vars intercept localhost and add localhost/127.0.0.1 to NO_PROXY
- Verify the session port is not occupied by another process and that the MLX server actually started
- Retry the request; transient health-check failures often clear on the next attempt
Example fix
// before
await chat(messages, model)
// after
try {
await chat(messages, model)
} catch (e) {
if (e.message.includes('crashed')) {
await mlx.reload(model.id)
await chat(messages, model)
}
} Defensive patterns
Strategy: try-catch
Validate before calling
async function isMlxHealthy(sessionInfo) {
try {
const res = await fetch(`http://127.0.0.1:${sessionInfo.port}/health`, { signal: AbortSignal.timeout(3000) })
return res.ok
} catch { return false }
}
if (!(await isMlxHealthy(sessionInfo))) await reloadModel(model.id) Type guard
const isAlive = (s) => typeof s === 'object' && s !== null && typeof s.port === 'number' && s.port > 0
Try / catch
try {
await chat(messages, model)
} catch (e) {
if (String(e.message).includes('crashed')) {
await reloadModel(model.id)
return chat(messages, model)
}
throw e
} Prevention
- Add NO_PROXY=localhost,127.0.0.1 in environments with HTTP proxies
- Poll /health before sending long-running requests
- Monitor MLX server memory to avoid OOM crashes
- Pin compatible mlx server and extension versions
When it happens
Trigger: Calling chat() while the MLX server process is running but its HTTP health endpoint at http://localhost:<port>/health cannot be reached — e.g. the server just died, the port changed, or a firewall/proxy intercepts localhost requests.
Common situations: The MLX server crashed mid-session (OOM, bad model weights), the port recorded in sessionInfo is stale after a restart, a system proxy env var routes localhost through a proxy, or IPv6/IPv4 localhost resolution issues.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- MLX model has crashed! Please reload!
- No running MLX session found for model
- error.message
- IO error
- MLX API request failed with status
AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17).
Data as JSON: /api/errors/4820bd60fe15f7f3.
Report an issue: GitHub.
Appendix: source
Thrown at extensions/mlx-extension/src/index.ts:405
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!')
}
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)
}
View on GitHub (pinned to 7205d770c1)