{"record":{"id":"b8772d3e7645921e","repo":"janhq/jan","slug":"mlxerror-code-code-message-message","errorCode":null,"errorMessage":"MlxError {{ code: {code:?}, message: \"{message}\" }}","messagePattern":"MlxError (.+?), message: \"(.+?)\" \\}\\}","errorType":"error_code","errorClass":"MlxError","httpStatus":null,"severity":"error","filePath":"src-tauri/plugins/tauri-plugin-mlx/src/error.rs","lineNumber":17,"sourceCode":"use serde::{Deserialize, Serialize};\n\n#[derive(Debug, Clone, Serialize, Deserialize)]\n#[serde(rename_all = \"SCREAMING_SNAKE_CASE\")]\npub enum ErrorCode {\n    BinaryNotFound,\n    ModelFileNotFound,\n    ModelLoadFailed,\n    ModelLoadTimedOut,\n    OutOfMemory,\n    MlxProcessError,\n    IoError,\n    InternalError,\n}\n\n#[derive(Debug, Clone, Serialize, thiserror::Error)]\n#[error(\"MlxError {{ code: {code:?}, message: \\\"{message}\\\" }}\")]\npub struct MlxError {\n    pub code: ErrorCode,\n    pub message: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub details: Option<String>,\n}\n\nimpl MlxError {\n    pub fn new(code: ErrorCode, message: String, details: Option<String>) -> Self {\n        Self {\n            code,\n            message,\n            details,\n        }\n    }\n\n    /// Parses stderr from the MLX server and creates a specific MlxError.\n    pub fn from_stderr(stderr: &str) -> Self {","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/src-tauri/plugins/tauri-plugin-mlx/src/error.rs#L1-L35","documentation":"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\"`).","triggerScenarios":"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.","commonSituations":"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`).","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."],"exampleFix":"// before - constructing with a raw string and no details\nreturn Err(MlxError::new(ErrorCode::ModelLoadFailed, \"load failed\".into(), None));\n\n// after - propagate the upstream cause into details\nlet stderr = String::from_utf8_lossy(&output.stderr).into_owned();\nreturn Err(MlxError::new(\n    ErrorCode::ModelLoadFailed,\n    \"MLX failed to load the model\".into(),\n    Some(stderr),\n));","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"fn is_recoverable(err: &MlxError) -> bool {\n    matches!(err.code, ErrorCode::BinaryNotFound | ErrorCode::ModelFileNotFound | ErrorCode::OutOfMemory)\n}","tryCatchPattern":"match run_mlx(&req).await {\n    Ok(out) => Ok(out),\n    Err(ServerError::Mlx(e)) => {\n        tracing::error!(code=?e.code, details=?e.details, \"mlx error\");\n        match e.code {\n            ErrorCode::BinaryNotFound => Err(UserError::SetupNeeded(\"install MLX\".into())),\n            ErrorCode::ModelFileNotFound => Err(UserError::NotFound(req.model.clone())),\n            _ => Err(UserError::MlxFailed(e.message)),\n        }\n    }\n    Err(e) => Err(e.into()),\n}","preventionTips":["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."],"tags":["mlx","error-format","thiserror","tauri","rust"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}