{"record":{"id":"d83373be42bb15b0","repo":"facebook/flow","slug":"content-of-file-input-unsafe-failed-to-read-file","errorCode":null,"errorMessage":"content_of_file_input_unsafe: failed to read file","messagePattern":"content_of_file_input_unsafe: failed to read file","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_server_utils/src/file_input.rs","lineNumber":36,"sourceCode":"        match self {\n            FileInput::FileName(f) => Some(f),\n            FileInput::FileContent(Some(f), _) => Some(f),\n            _ => None,\n        }\n    }\n\n    pub fn filename_of_file_input(&self) -> &str {\n        match self {\n            FileInput::FileName(f) => f,\n            FileInput::FileContent(Some(f), _) => f,\n            FileInput::FileContent(None, _) => \"-\",\n        }\n    }\n\n    pub fn content_of_file_input_unsafe(&self) -> String {\n        match self {\n            FileInput::FileName(f) => std::fs::read_to_string(f)\n                .expect(\"content_of_file_input_unsafe: failed to read file\"),\n            FileInput::FileContent(_, content) => content.to_string(),\n        }\n    }\n\n    pub fn content_of_file_input(&self) -> Result<String, String> {\n        match self {\n            FileInput::FileName(f) => std::fs::read_to_string(f).map_err(|e| format!(\"{}\", e)),\n            FileInput::FileContent(_, content) => Ok(content.to_string()),\n        }\n    }\n\n    pub fn content_of_file_input_arc(&self) -> Result<Arc<str>, String> {\n        match self {\n            FileInput::FileName(f) => std::fs::read_to_string(f)\n                .map(Arc::<str>::from)\n                .map_err(|e| format!(\"{}\", e)),\n            FileInput::FileContent(_, content) => Ok(content.clone()),\n        }","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_server_utils/src/file_input.rs#L18-L54","documentation":"FileInput::content_of_file_input_unsafe reads the file named by the FileName variant with std::fs::read_to_string and expects success (rust_port/crates/flow_server_utils/src/file_input.rs:31-37). It panics when the path does not exist, permissions block the read, or the bytes are not valid UTF-8. The crate deliberately ships the safe twin content_of_file_input() returning Result<String, String>; calling the _unsafe variant is opting into a process-killing panic on ordinary I/O failure.","triggerScenarios":"Calling content_of_file_input_unsafe() on FileInput::FileName(p) where p is missing, unreadable, or non-UTF-8 (binary or legacy-encoded files). FileContent variants return the inlined string and can never panic here.","commonSituations":"Server code paths that took the shortcut variant; stale paths after file deletion or rename; path mismatches across container bind mounts or operating systems; files in non-UTF-8 encodings.","solutions":["Switch to content_of_file_input() (or content_of_file_input_arc()) and handle Err(String) as a normal error","Verify the path exists and is readable before constructing FileInput::FileName; prefer FileInput::FileContent to inline contents","If non-UTF-8 input is legitimate, read the bytes and transcode explicitly rather than relying on read_to_string","Grep for remaining content_of_file_input_unsafe call sites and remove them"],"exampleFix":"// before\nlet content = input.content_of_file_input_unsafe();\n\n// after\nlet content = input\n    .content_of_file_input()\n    .map_err(|e| format!(\"failed to read {}: {e}\", input.filename_of_file_input()))?;","handlingStrategy":"type-guard","validationCode":"// Narrow the enum before reading: only FileName can fail\nif matches!(input, FileInput::FileName(_)) {\n    let meta = std::fs::metadata(input.filename_of_file_input());\n    if meta.is_err() || !meta.unwrap().is_file() {\n        return Err(format!(\"input file missing: {}\", input.filename_of_file_input()));\n    }\n}","typeGuard":"fn safe_content(input: &FileInput) -> Result<String, String> {\n    match input {\n        FileInput::FileName(f) => std::fs::read_to_string(f).map_err(|e| e.to_string()),\n        FileInput::FileContent(_, c) => Ok(c.to_string()),\n    }\n}","tryCatchPattern":null,"preventionTips":["Ban content_of_file_input_unsafe in code review; use the Result-returning twin","Prefer FileContent when the client already has the text","Handle non-UTF-8 sources explicitly instead of relying on read_to_string"],"tags":["file-io","file-input","panic","utf8","server-utils"],"backgroundTag":"file-read-failed","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","contentChangedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}