janhq/jan · error
error.message
Error message
error.message
What it means
The MLX server can send SSE lines of the form 'error: {json}'; the extension parses the JSON and rethrows its message field verbatim. This is a pass-through of a server-side streaming error, so the text varies (load failure, generation error, out-of-memory, etc.).
Solutions
- Read the propagated message for the concrete server-side cause
- Check MLX server logs/stderr at the time of the failure
- Verify model files are intact (re-download if corrupted)
- Update server and extension to matching versions
Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
const isSseErrorLine = (line) => line.startsWith('error: ') && (() => { try { return typeof JSON.parse(line.slice(7))?.message === 'string' } catch { return false } })() Try / catch
try {
for await (const chunk of streamChat(messages, model)) handle(chunk)
} catch (e) {
logger.error('MLX stream error:', e.message)
await reloadModel(model.id) // server-side failure: safest recovery is reload
throw e
} Prevention
- Capture MLX server stderr alongside the stream for correlation
- Reload the model after any mid-stream server error
- Keep server/extension versions matched to avoid protocol drift
- Verify model file integrity after failed generations
When it happens
Trigger: During handleStreamingResponse, a streamed line starts with 'error: ' and its JSON contains {message: ...} — the server failed during generation (e.g. model error, memory exhaustion, invalid request detected mid-stream).
Common situations: MLX server hitting memory limits while generating, corrupted model weights, incompatibilities between server and extension streaming protocol versions.
Related errors
AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17).
Data as JSON: /api/errors/9391f8eb1a95e5c4.
Report an issue: GitHub.
Appendix: source
Thrown at extensions/mlx-extension/src/index.ts:524
if (trimmedLine.startsWith('data: ')) {
const jsonStr = trimmedLine.slice(6)
try {
const data = JSON.parse(jsonStr) as chatCompletionChunk
if (data.choices?.[0]?.finish_reason === 'length') {
throw new Error(OUT_OF_CONTEXT_SIZE)
}
yield data
} catch (e) {
logger.error('Error parsing MLX stream JSON:', e)
throw e
}
} else if (trimmedLine.startsWith('error: ')) {
const jsonStr = trimmedLine.slice(7)
const error = JSON.parse(jsonStr)
throw new Error(error.message)
}
}
}
} finally {
reader.releaseLock()
}
}
override async delete(modelId: string): Promise<void> {
const modelDir = await joinPath([
await this.getProviderPath(),
'models',
modelId,
])
const modelConfigPath = await joinPath([modelDir, 'model.yml'])
if (!(await fs.existsSync(modelConfigPath))) {
throw new Error(`Model ${modelId} does not exist`)View on GitHub (pinned to 7205d770c1)