{"record":{"id":"33d5cdb42038f80c","repo":"janhq/jan","slug":"unsupported-file-type-0","errorCode":null,"errorMessage":"Unsupported file type: {0}","messagePattern":"Unsupported file type: (.+?)","errorType":"validation","errorClass":"RagError::UnsupportedFileType","httpStatus":null,"severity":"warning","filePath":"src-tauri/plugins/tauri-plugin-rag/src/error.rs","lineNumber":8,"sourceCode":"use serde::{Deserialize, Serialize};\n\n#[derive(Debug, thiserror::Error, Serialize, Deserialize)]\npub enum RagError {\n    #[error(\"Failed to parse document: {0}\")]\n    ParseError(String),\n\n    #[error(\"Unsupported file type: {0}\")]\n    UnsupportedFileType(String),\n\n    #[error(\"IO error: {0}\")]\n    IoError(String),\n}\n\nimpl From<std::io::Error> for RagError {\n    fn from(err: std::io::Error) -> Self {\n        RagError::IoError(err.to_string())\n    }\n}\n\n","sourceCodeStart":1,"sourceCodeEnd":21,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/src-tauri/plugins/tauri-plugin-rag/src/error.rs#L1-L21","documentation":"`RagError::UnsupportedFileType(String)` is returned when a file extension or MIME signature is not in the set of formats the RAG plugin can ingest. The wrapped string identifies the offending type. It is a pure validation error — the file may be perfectly valid; the plugin simply does not know how to handle it.","triggerScenarios":"Passing a file whose extension is not in the supported list (e.g. `.xlsx`, `.heic`, `.mp4`, `.zip`) to the ingestion API; a file with no extension; a file whose declared type does not match any registered parser.","commonSituations":"Users dragging arbitrary files into the ingestion UI; misconfigured MIME detection that reports an unexpected type; a backend that needs to be extended to support a new format.","solutions":["Filter files at the UI layer by allowed extensions before they reach the ingestion API.","If the format is required, add a parser for it in the RAG plugin.","Surface a clear user-facing message naming the unsupported type so the user can convert the file.","For files with no extension, sniff the magic bytes to determine the real type."],"exampleFix":"// before\nlet parsed = rag.ingest(&path)?;\n\n// after - pre-filter with a clear error\nconst SUPPORTED: &[&str] = &[\"pdf\", \"docx\", \"md\", \"txt\", \"html\"];\nlet ext = path.extension().and_then(|e| e.to_str()).unwrap_or(\"\").to_lowercase();\nif !SUPPORTED.contains(&ext.as_str()) {\n    return Err(RagError::UnsupportedFileType(ext));\n}\nlet parsed = rag.ingest(&path)?;","handlingStrategy":"validation","validationCode":"const SUPPORTED: &[&str] = &[\"pdf\", \"docx\", \"md\", \"txt\", \"html\"];\nfn supported_ext(path: &Path) -> Result<String, RagError> {\n    let ext = path.extension().and_then(|e| e.to_str()).unwrap_or(\"\").to_lowercase();\n    if SUPPORTED.contains(&ext.as_str()) { Ok(ext) } else { Err(RagError::UnsupportedFileType(ext)) }\n}","typeGuard":"fn is_supported(path: &Path) -> bool {\n    matches!(path.extension().and_then(|e| e.to_str()).map(str::to_lowercase).as_deref(),\n        Some(\"pdf\") | Some(\"docx\") | Some(\"md\") | Some(\"txt\") | Some(\"html\"))\n}","tryCatchPattern":"match rag.ingest(&path).await {\n    Ok(doc) => Ok(doc),\n    Err(RagError::UnsupportedFileType(t)) => {\n        Err(UserError::UnsupportedFile(t))\n    }\n    Err(e) => Err(e.into()),\n}","preventionTips":["Restrict the file picker to supported extensions in the UI.","Sniff magic bytes for files with no extension before rejecting.","Surface the unsupported type to the user so they can convert."],"tags":["rag","validation","file-type","tauri","rust"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}