{"record":{"id":"c3a590da97a4d1c6","repo":"xai-org/grok-build","slug":"failed-to-read-path-e","errorCode":null,"errorMessage":"Failed to read '{path}': {e}","messagePattern":"Failed to read '(.+?)': (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-pager/src/headless/cli.rs","lineNumber":61,"sourceCode":"        if let Some(text) = single {\n            Self::from_text(text)\n                .map(Some)\n                .map_err(|e| anyhow::anyhow!(\"--single: {e}\"))\n        } else if let Some(json_str) = prompt_json {\n            Self::from_json(json_str)\n                .map(Some)\n                .map_err(|e| anyhow::anyhow!(\"--prompt-json: {e}\"))\n        } else if let Some(path) = prompt_file {\n            Self::from_file(path).map(Some)\n        } else {\n            Ok(None)\n        }\n    }\n\n    /// `.json` files are parsed as content blocks, everything else as text.\n    pub fn from_file(path: &Path) -> anyhow::Result<Self> {\n        let content = std::fs::read_to_string(path)\n            .map_err(|e| anyhow::anyhow!(\"Failed to read '{}': {e}\", path.display()))?;\n\n        let context = |e| anyhow::anyhow!(\"'{}': {e}\", path.display());\n        if path.extension().and_then(|e| e.to_str()) == Some(\"json\") {\n            Self::from_json(&content).map_err(context)\n        } else {\n            Self::from_text(&content).map_err(context)\n        }\n    }\n\n    fn from_text(text: &str) -> anyhow::Result<Self> {\n        let trimmed = text.trim();\n        if trimmed.is_empty() {\n            anyhow::bail!(\"prompt is empty\");\n        }\n        Ok(Self::Text(trimmed.to_string()))\n    }\n\n    fn from_json(json_str: &str) -> anyhow::Result<Self> {","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-pager/src/headless/cli.rs#L43-L79","documentation":"PromptSource::from_file wraps std::fs::read_to_string failures as \"Failed to read '{path}': {e}\". The prompt file could not be opened or decoded as UTF-8 (missing file, permission denied, directory passed, or invalid encoding).","triggerScenarios":"Calling --prompt-file with a path that does not exist, is unreadable (permissions), is a directory, or contains non-UTF-8 bytes.","commonSituations":"Typo in the path; running from a different working directory with a relative path; CI checkout missing the file; file saved with UTF-16/BOM from a Windows editor.","solutions":["Verify the path exists and is readable (ls -l / test -r)","Use an absolute path or resolve relative to the script's directory","Re-save the file as UTF-8 without BOM","Check the inner {e} (NotFound/PermissionDenied/InvalidData) for the exact cause"],"exampleFix":"# before\npager --prompt-file prompts/task.txt\n# after\npager --prompt-file \"$(pwd)/prompts/task.txt\"","handlingStrategy":"validation","validationCode":"fn ensure_readable_prompt_file(path: &std::path::Path) -> Result<(), String> {\n    if !path.is_file() { return Err(format!(\"not a file: {}\", path.display())); }\n    let meta = std::fs::metadata(path).map_err(|e| e.to_string())?;\n    if meta.len() == 0 { return Err(\"file is empty\".into()); }\n    std::fs::read_to_string(path).map(|_| ()).map_err(|e| e.to_string())\n}","typeGuard":"fn is_readable_utf8_file(p: &std::path::Path) -> bool {\n    p.is_file() && std::fs::read_to_string(p).is_ok()\n}","tryCatchPattern":"match PromptSource::from_file(&path) {\n    Ok(src) => src,\n    Err(e) => {\n        if e.to_string().contains(\"Failed to read\") {\n            eprintln!(\"prompt file unreadable: {e:#}\"); std::process::exit(2);\n        }\n        return Err(e);\n    }\n}","preventionTips":["Use absolute paths resolved from the script location","Check file existence and readability before invoking","Ensure files are UTF-8 without BOM","Ship prompt files with the deployment artifact, not ad hoc"],"tags":["file-io","cli","prompt","rust"],"backgroundTag":"file-not-found","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}