{"record":{"id":"11398c2cd9cccd47","repo":"janhq/jan","slug":"io-error-0-11398c","errorCode":null,"errorMessage":"IO error: {0}","messagePattern":"IO error: (.+?)","errorType":"exception","errorClass":"ServerError::Io","httpStatus":null,"severity":"error","filePath":"src-tauri/plugins/tauri-plugin-mlx/src/error.rs","lineNumber":62,"sourceCode":"                \"Out of memory. The model requires more RAM than available.\".into(),\n                Some(stderr.into()),\n            );\n        }\n\n        Self::new(\n            ErrorCode::MlxProcessError,\n            \"The MLX model process encountered an unexpected error.\".into(),\n            Some(stderr.into()),\n        )\n    }\n}\n\n#[derive(Debug, thiserror::Error)]\npub enum ServerError {\n    #[error(transparent)]\n    Mlx(#[from] MlxError),\n\n    #[error(\"IO error: {0}\")]\n    Io(#[from] std::io::Error),\n\n    #[error(\"Tauri error: {0}\")]\n    Tauri(#[from] tauri::Error),\n}\n\nimpl serde::Serialize for ServerError {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        let error_to_serialize: MlxError = match self {\n            ServerError::Mlx(err) => err.clone(),\n            ServerError::Io(e) => MlxError::new(\n                ErrorCode::IoError,\n                \"An input/output error occurred.\".into(),\n                Some(e.to_string()),\n            ),","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/src-tauri/plugins/tauri-plugin-mlx/src/error.rs#L44-L80","documentation":"`ServerError::Io` wraps any `std::io::Error` propagated out of the MLX plugin (via `#[from]`). It fires when the plugin itself hits an I/O problem — not the MLX subprocess: e.g. the model file cannot be opened, a temp file cannot be written, or a pipe to the subprocess cannot be created. The custom `Serialize` impl converts this variant into an `MlxError` with `ErrorCode::IoError` before serializing.","triggerScenarios":"Opening a model file that does not exist or is not readable; creating a named pipe / socket to talk to MLX and failing; writing cache or log files to a directory without permission; the subprocess stdin/stdout pipe returning EPIPE.","commonSituations":"Wrong model path; permission errors on the model directory or cache directory; disk full; broken pipe when the MLX process exits while the plugin is still writing to its stdin.","solutions":["Inspect the wrapped `io::Error` — its `kind()` tells you NotFound, PermissionDenied, BrokenPipe, etc.","For NotFound, verify the path the plugin resolved (log it before opening).","For PermissionDenied, check filesystem permissions on the model and cache directories.","For BrokenPipe, handle the case where the MLX process exits mid-write (often a downstream crash — see the MlxProcessError)."],"exampleFix":"// before\nlet f = File::open(&path)?;\n\n// after - map io::Error to a richer MlxError with context\nlet f = File::open(&path).map_err(|e| match e.kind() {\n    io::ErrorKind::NotFound => MlxError::new(ErrorCode::ModelFileNotFound, format!(\"{} not found\", path.display()), None),\n    _ => MlxError::new(ErrorCode::IoError, e.to_string(), Some(format!(\"{}\", path.display()))),\n})?;","handlingStrategy":"try-catch","validationCode":"fn ensure_readable(path: &Path) -> io::Result<()> {\n    std::fs::File::open(path).map(|_| ())\n}","typeGuard":"null","tryCatchPattern":"match run_mlx(&req).await {\n    Ok(out) => Ok(out),\n    Err(ServerError::Io(e)) if e.kind() == io::ErrorKind::NotFound => {\n        Err(UserError::NotFound(req.model.clone()))\n    }\n    Err(ServerError::Io(e)) if e.kind() == io::ErrorKind::PermissionDenied => {\n        Err(UserError::PermissionDenied(req.model.clone()))\n    }\n    Err(e) => Err(e.into()),\n}","preventionTips":["Check the model path exists and is readable before launching MLX.","Inspect `io::Error::kind()` to give users actionable messages.","Handle BrokenPipe as a likely subprocess crash and re-check the process state."],"tags":["mlx","io","filesystem","tauri","rust"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}