{"record":{"id":"f661ca636c1c0101","repo":"uutils/coreutils","slug":"is-a-directory","errorCode":null,"errorMessage":"Is a directory","messagePattern":"Is a directory","errorType":"console","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"src/uucore/src/lib/features/checksum/validate.rs","lineNumber":570,"sourceCode":"                FileChecksumResult::CantOpen,\n                opts.verbose,\n            );\n        };\n        let print_error = |err: io::Error| {\n            show!(err.map_err_context(|| {\n                locale_aware_escape_name(filename, QuotingStyle::SHELL_ESCAPE)\n                    // This is non destructive thanks to the escaping\n                    .to_string_lossy()\n                    .to_string()\n            }));\n        };\n        match File::open(filename) {\n            Ok(f) => {\n                if f.metadata()\n                    .map_err(|_| LineCheckError::CantOpenFile)?\n                    .is_dir()\n                {\n                    print_error(io::Error::new(\n                        io::ErrorKind::IsADirectory,\n                        \"Is a directory\",\n                    ));\n                    // also regarded as a failed open\n                    failed_open();\n                    Err(LineCheckError::FileIsDirectory)\n                } else {\n                    Ok(Box::new(f))\n                }\n            }\n            Err(err) => {\n                if !opts.ignore_missing {\n                    // yes, we have both stderr and stdout here\n                    print_error(err);\n                    failed_open();\n                }\n                // we could not open the file but we want to continue\n                Err(LineCheckError::FileNotFound)","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/uutils/coreutils/blob/85295bbf788bfd7a6926ba692031563504b304b7/src/uucore/src/lib/features/checksum/validate.rs#L552-L588","documentation":"During checksum validation (`get_file_to_check`), opening a file that turns out to be a directory produces an explicit `io::ErrorKind::IsADirectory` error printed as \"Is a directory\", the open is counted as a failed open, and `LineCheckError::FileIsDirectory` is returned so the line of the checksum file is treated as failed.","triggerScenarios":"A checksum file lists a path that is actually a directory; `compute_and_check_digest_from_file` hits it while iterating listed paths and calls `File::open(filename)`, which succeeds on some platforms, then metadata shows `is_dir()`.","commonSituations":"Checksum manifests generated with wildcards that matched directories, hand-edited .sha256/.md5 files, or renamed files replaced by directories of the same name.","solutions":["Remove the directory entry from the checksum file","Re-generate the checksum file so it contains only regular files","Verify the expected file wasn't replaced by a directory"],"exampleFix":"# before\nsha256sum * > checksums.sha256   # may include directories\n# after\nfind . -type f -exec sha256sum {} + > checksums.sha256","handlingStrategy":"validation","validationCode":"let md = std::fs::metadata(path)?;\nif md.is_dir() {\n    eprintln!(\"skipping directory: {}\", path.display());\n} else {\n    validate_checksum(path)?;\n}","typeGuard":"fn is_regular_file(p: &Path) -> bool {\n    std::fs::metadata(p).map(|m| m.is_file()).unwrap_or(false)\n}","tryCatchPattern":"match validate_checksum(path) {\n    Err(e) if e.to_string() == \"Is a directory\" => skip_entry(path),\n    other => other?,\n}","preventionTips":["Generate checksum files with find -type f, not bare wildcards","Skip non-regular files before hashing","Validate manifests after hand edits"],"tags":["checksum","io","filesystem"],"backgroundTag":"is-a-directory","analyzedSha":"85295bbf788bfd7a6926ba692031563504b304b7","analyzedAt":"2026-08-31T11:11:36.175Z","contentChangedAt":"2026-08-31T11:11:36.175Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}