{"record":{"id":"8c5653b7f8ca4ec2","repo":"can1357/oh-my-pi","slug":"truncated-getattrlistbulk-record-length","errorCode":null,"errorMessage":"truncated getattrlistbulk record length","messagePattern":"truncated getattrlistbulk record length","errorType":"error_code","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/pi-walker/src/lib.rs","lineNumber":3657,"sourceCode":"\tconst fn file_type_from_vtype(value: u32) -> Option<FileType> {\n\t\tmatch value {\n\t\t\tVREG => Some(FileType::File),\n\t\t\tVDIR => Some(FileType::Dir),\n\t\t\tVLNK => Some(FileType::Symlink),\n\t\t\t_ => None,\n\t\t}\n\t}\n\n\tfn is_unsupported_dir_scan(err: &io::Error) -> bool {\n\t\tmatches!(err.raw_os_error(), Some(libc::ENOTSUP | libc::EINVAL))\n\t}\n\n\tfn is_skippable_entry_error(err: &io::Error) -> bool {\n\t\tmatches!(err.kind(), io::ErrorKind::NotFound | io::ErrorKind::PermissionDenied)\n\t}\n\n\tfn invalid_data(message: &'static str) -> io::Error {\n\t\tio::Error::new(io::ErrorKind::InvalidData, message)\n\t}\n}\n\n#[cfg(target_os = \"linux\")]\nmod platform {\n\tuse std::{\n\t\tffi::{CString, OsStr},\n\t\tio,\n\t\tmem::{size_of, zeroed},\n\t\tos::unix::ffi::OsStrExt,\n\t\tpath::Path,\n\t};\n\n\tuse super::{\n\t\tFileType, RawDirEntry, ReadDirControl, ReadDirError, WalkDetail, WalkError, mtime_millis,\n\t};\n\n\tpub const CHEAP_SIZE_HINTS: bool = false;","sourceCodeStart":3639,"sourceCodeEnd":3675,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/crates/pi-walker/src/lib.rs#L3639-L3675","documentation":"On macOS, pi-walker parses fixed-size records returned by getattrlistbulk; if a record header claims a length that would run past the buffer or below the minimum size, the walker treats the buffer as corrupt and returns InvalidData with this static message. It protects against kernel/libc contract violations rather than user input.","triggerScenarios":"getattrlistbulk returns a buffer whose record's attr_length is smaller than the fixed header or larger than the remaining buffer, during directory enumeration on macOS.","commonSituations":"OS/driver bugs, exotic filesystems (network mounts, FUSE) whose getattrlistbulk response is malformed, or hardware/memory corruption.","solutions":["Retry the directory listing once; transient buffer corruption on network filesystems may clear.","Fall back to a portable readdir-based walker (the no-special-casing std::fs::read_dir path) for that filesystem.","Report the filesystem type and macOS version — this indicates a platform-level defect, not caller error."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"match fast_walk(dir) {\n  Err(e) if e.kind() == io::ErrorKind::InvalidData => std_walk(dir), // read_dir fallback\n  other => other,\n}","preventionTips":["Keep a portable std::fs::read_dir fallback path for macOS enumeration.","Avoid network/FUSE mounts when using the fast walker.","Retry once before falling back; corruption can be transient."],"tags":["filesystem","macos","invalid-data","truncated-record"],"backgroundTag":"truncated-directory-record","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}