{"record":{"id":"09e7bcae4525e07a","repo":"can1357/oh-my-pi","slug":"cannot-read","errorCode":null,"errorMessage":"cannot read: {}: {}","messagePattern":"cannot read: (.+?): (.+?)","errorType":"exception","errorClass":"SortError","httpStatus":null,"severity":"error","filePath":"crates/pi-builtins/src/sort.rs","lineNumber":2602,"sourceCode":"const MIN_AUTOMATIC_BUF_SIZE: usize = 512 * 1024; // 512 KiB\nconst FALLBACK_AUTOMATIC_BUF_SIZE: usize = 32 * 1024 * 1024; // 32 MiB\nconst MAX_AUTOMATIC_BUF_SIZE: usize = 1024 * 1024 * 1024; // 1 GiB\n\n#[derive(Debug, Error)]\npub enum SortError {\n\t#[error(\"{0}\")]\n\tMessage(String),\n\n\t#[error(\"write failed: {}: {}\", .path.maybe_quote(), strip_errno(.error))]\n\tWriteFailed { path: OsString, error: std::io::Error },\n\n\t#[error(\"{}\", format_disorder(.file, .line_number, .line, .silent))]\n\tDisorder { file: OsString, line_number: usize, line: String, silent: bool },\n\n\t#[error(\"open failed: {}: {}\", .path.maybe_quote(), strip_errno(.error))]\n\tOpenFailed { path: PathBuf, error: std::io::Error },\n\n\t#[error(\"cannot read: {}: {}\", .path.maybe_quote(), strip_errno(.error))]\n\tReadFailed { path: PathBuf, error: std::io::Error },\n\n\t#[error(\"failed to open temporary file: {}\", strip_errno(.error))]\n\tOpenTmpFileFailed { error: std::io::Error },\n\n\t#[error(\"could not run compress program '{}': {}\", .prog, strip_errno(.error))]\n\tCompressProgExecutionFailed { prog: String, error: std::io::Error },\n\n\t#[error(\"{} terminated abnormally\", .prog.quote())]\n\tCompressProgTerminatedAbnormally { prog: String },\n\n\t#[error(\"cannot create temporary file in {}:\", .path.quote())]\n\tTmpFileCreationFailed { path: PathBuf },\n\n\t#[error(\"extra operand {}\\nfile operands cannot be combined with --files0-from\\nTry 'sort --help' for more information.\", .file.quote())]\n\tFileOperandsCombined { file: PathBuf },\n\n","sourceCodeStart":2584,"sourceCodeEnd":2620,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/crates/pi-builtins/src/sort.rs#L2584-L2620","documentation":"`SortError::ReadFailed` occurs when the sort builtin cannot read from an already-opened file, quoting the path and the stripped errno. Unlike OpenFailed, the open succeeded but a subsequent read operation failed (I/O error, EISDIR on read, hardware error).","triggerScenarios":"A read syscall on an input or temp file fails mid-sort — e.g. device I/O error, file truncated concurrently by another process, or attempting to read a special file that rejects reads.","commonSituations":"NFS/network filesystem staleness or timeouts; concurrent modification or truncation of the input while sorting; failing disk sectors.","solutions":["Re-run the sort; transient network/IO errors often clear.","Check filesystem health (`dmesg`, `smartctl`) if errors persist.","Ensure no other process truncates/rewrites the file during the sort (snapshot or copy first).","Copy the file to local disk before sorting if it lives on an unreliable network mount."],"exampleFix":"// before\nsort /mnt/nfs/live.log\n\n// after\ncp /mnt/nfs/live.log /tmp/live.snapshot.log && sort /tmp/live.snapshot.log","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// transient read errors warrant a bounded retry\nfor attempt in 1..=3 {\n    match run_sort() {\n        Err(SortError::ReadFailed { path, error }) => {\n            eprintln!(\"attempt {attempt}: read {} failed: {error}\", path.display());\n            sleep(Duration::from_secs(2u64.pow(attempt - 1)));\n        }\n        other => { other?; break; }\n    }\n}","preventionTips":["Snapshot inputs to local disk before sorting network-resident files.","Avoid concurrent writers to files being sorted.","Monitor filesystem health; persistent read errors indicate failing storage."],"tags":["sort","io","filesystem","read"],"backgroundTag":"file-read-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}