janhq/jan · error · MlxError
MlxError {{ code: {code:?}, message: "{message}" }}
Error message
MlxError {{ code: {code:?}, message: "{message}" }} What it means
Display format for the `MlxError` struct, used for any error originating inside the MLX plugin. The struct carries an `ErrorCode` variant (BinaryNotFound, ModelFileNotFound, ModelLoadFailed, ModelLoadTimedOut, OutOfMemory, MlxProcessError, IoError, InternalError), a human-readable message, and an optional `details` string. The `thiserror` `#[error(...)]` attribute renders all three into the displayed string; the `details` field is included in serialization only when present (`skip_serializing_if = "Option::is_none"`).
Source
Thrown at src-tauri/plugins/tauri-plugin-mlx/src/error.rs:17
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ErrorCode {
BinaryNotFound,
ModelFileNotFound,
ModelLoadFailed,
ModelLoadTimedOut,
OutOfMemory,
MlxProcessError,
IoError,
InternalError,
}
#[derive(Debug, Clone, Serialize, thiserror::Error)]
#[error("MlxError {{ code: {code:?}, message: \"{message}\" }}")]
pub struct MlxError {
pub code: ErrorCode,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub details: Option<String>,
}
impl MlxError {
pub fn new(code: ErrorCode, message: String, details: Option<String>) -> Self {
Self {
code,
message,
details,
}
}
/// Parses stderr from the MLX server and creates a specific MlxError.
pub fn from_stderr(stderr: &str) -> Self {View on GitHub (pinned to fad3f12a14)
Solutions
- Read the `code` field first — it tells you which category of failure occurred and which fix to apply.
- For BinaryNotFound, install/locate the MLX runtime and verify the path the plugin resolves.
- For ModelFileNotFound / ModelLoadFailed, verify the model path exists, is readable, and is a valid MLX-format model.
- For OutOfMemory, reduce the model size or context, or free memory.
- For MlxProcessError, inspect the captured stderr in `details` for the upstream cause.
Example fix
// before - constructing with a raw string and no details
return Err(MlxError::new(ErrorCode::ModelLoadFailed, "load failed".into(), None));
// after - propagate the upstream cause into details
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
return Err(MlxError::new(
ErrorCode::ModelLoadFailed,
"MLX failed to load the model".into(),
Some(stderr),
)); Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
fn is_recoverable(err: &MlxError) -> bool {
matches!(err.code, ErrorCode::BinaryNotFound | ErrorCode::ModelFileNotFound | ErrorCode::OutOfMemory)
} Try / catch
match run_mlx(&req).await {
Ok(out) => Ok(out),
Err(ServerError::Mlx(e)) => {
tracing::error!(code=?e.code, details=?e.details, "mlx error");
match e.code {
ErrorCode::BinaryNotFound => Err(UserError::SetupNeeded("install MLX".into())),
ErrorCode::ModelFileNotFound => Err(UserError::NotFound(req.model.clone())),
_ => Err(UserError::MlxFailed(e.message)),
}
}
Err(e) => Err(e.into()),
} Prevention
- Always branch on the `code` field rather than parsing the message string.
- Capture subprocess stderr into `details` for every process failure.
- Surface actionable categories (setup, not-found, oom) distinctly to the user.
When it happens
Trigger: Any code path that constructs `MlxError::new(code, message, details)` and propagates it. This includes failing to locate the MLX binary, failing to find the model file, the MLX process crashing, an out-of-memory condition, or an internal plugin error. The same format is reused across all those variants, so the discriminant is the `code` field, not the message.
Common situations: End-user machines without the MLX Python package installed (`BinaryNotFound`), a typo in the model path (`ModelFileNotFound`), an incompatible or corrupted model (`ModelLoadFailed`), insufficient RAM/VRAM (`OutOfMemory`), or the MLX subprocess exiting non-zero (`MlxProcessError`, with stderr captured into `details`).
Related errors
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/b8772d3e7645921e.
Report an issue: GitHub.