janhq/jan · error · RagError
IoError
IoError
Error message
IO error: {0} What it means
RagError::IoError wraps a std::io::Error as a string when filesystem operations fail during RAG ingestion or retrieval (displayed as "IO error: {0}"). Via the provided From impl, any std::io::Error from reading files or accessing paths is converted automatically. It indicates OS-level IO trouble, not document parsing or format issues.
Solutions
- Read the wrapped message to identify the exact OS error (NotFound vs PermissionDenied).
- Verify the file path exists and is readable before ingestion (fs::metadata check).
- Ensure the plugin's index/storage directories exist and are writable.
- Handle transient failures (network drives) with a retry around ingestion.
Example fix
// before
let text = read_document(path)?;
// after
let text = read_document(path).map_err(|e| match e {
RagError::IoError(msg) => {
eprintln!("cannot read {path:?}: {msg}");
e
}
other => other,
})?; Defensive patterns
Strategy: validation
Validate before calling
// Rust: verify the file is readable before RAG operations
fn readable(path: &Path) -> bool {
std::fs::File::open(path).is_ok()
} Type guard
fn as_io_error(err: &RagError) -> Option<&str> {
match err { RagError::IoError(m) => Some(m), _ => None }
} Try / catch
match rag.ingest(path) {
Err(RagError::IoError(msg)) => {
log::warn!("io problem with {path:?}: {msg}");
retry_with_backoff(|| rag.ingest(path));
}
other => other?,
} Prevention
- Check file existence and permissions before ingestion.
- Create the plugin's index/storage directories at startup.
- Retry transient IO failures (network mounts) with backoff.
- Watch for files disappearing between selection and ingestion in UI flows.
When it happens
Trigger: Ingesting a file that doesn't exist, lacks read permission, or was deleted mid-operation; failing to create/write index or cache directories used by the RAG plugin.
Common situations: Moved or renamed files between selection and ingestion; permission-restricted folders; missing index directory on first run; network mounts dropped mid-read.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17).
Data as JSON: /api/errors/3fa3be1116f803ea.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/plugins/tauri-plugin-rag/src/error.rs:11
use serde::{Deserialize, Serialize};
#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
pub enum RagError {
#[error("Failed to parse document: {0}")]
ParseError(String),
#[error("Unsupported file type: {0}")]
UnsupportedFileType(String),
#[error("IO error: {0}")]
IoError(String),
}
impl From<std::io::Error> for RagError {
fn from(err: std::io::Error) -> Self {
RagError::IoError(err.to_string())
}
}
View on GitHub (pinned to 7205d770c1)