{"record":{"id":"d8f6b7c9fd3ae7f1","repo":"vercel/turborepo","slug":"path-not-a-regular-file","errorCode":null,"errorMessage":"{path}: not a regular file","messagePattern":"(.+?): not a regular file","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/turborepo-scm/src/crlf.rs","lineNumber":333,"sourceCode":"}\n\n/// Hash a byte slice as a git blob. Used to verify symlink entries, whose\n/// blob content is the link target path (no filters ever apply).\npub(crate) fn hash_bytes_as_blob(bytes: &[u8]) -> Result<OidHash, std::io::Error> {\n    let mut hasher = BlobHasher::new();\n    hasher.write_blob_header(bytes.len() as u64);\n    hasher.update(bytes);\n    hasher.finalize()\n}\n\nfn validate_file_type(\n    path: &AbsoluteSystemPath,\n    metadata: &std::fs::Metadata,\n) -> Result<(), std::io::Error> {\n    // Reject exotic file types (sockets, FIFOs, device nodes). Directories\n    // pass through to fail naturally with a descriptive IsADirectory error.\n    if !metadata.is_file() && !metadata.is_dir() {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidInput,\n            format!(\"{path}: not a regular file\"),\n        ));\n    }\n    Ok(())\n}\n\n/// Hash a file as a git blob, applying CRLF→LF normalization when the\n/// `text` attribute requires it.\n///\n/// For `TextAttr::Auto`, binary detection (NUL in first 8KB) is performed\n/// during the fused scan+hash pass — no separate file open.\n///\n/// Single-pass for the common case (no normalization needed):\n/// 1. Get file length from metadata\n/// 2. Fused scan + speculative raw hash: write blob header, then scan for CRLFs\n///    while simultaneously feeding raw bytes into the hasher\n/// 3. If no normalization needed, return the raw hash (one read total)","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/vercel/turborepo/blob/7fe373bc270adb30db3c184c55069f77feb1a6d6/crates/turborepo-scm/src/crlf.rs#L315-L351","documentation":"When hashing workspace files for the cache key, the CRLF-aware blob hasher first validates the file type (crlf.rs:333): anything that is neither a regular file nor a directory — sockets, FIFOs, char/block devices — is rejected with InvalidInput '{path}: not a regular file'. Directories deliberately pass through to fail later with a descriptive IsADirectory error; this guard targets exotic node types that would otherwise hash garbage or hang on a FIFO.","triggerScenarios":"A glob/task input in turbo.json matching a Unix socket or named pipe inside the workspace — e.g. a dev server dropped a *.sock file, or a tools directory contains an mkfifo artifact that a broad `inputs` pattern picks up.","commonSituations":"dev/.sock or *.socket files created by local daemons inside the repo FIFOs from ad-hoc scripts left in the tree Repo unpacked over a path containing device nodes (rare)","solutions":["Find the offending entry: the message names the exact path; `file <path>` confirms the type","Delete it or move the tool that creates it outside the workspace","Tighten turbo.json `inputs` globs to specific extensions/dirs so sockets and FIFOs are excluded"],"exampleFix":"// before (turbo.json)\n\"inputs\": [\"**/*\"]\n// after — exclude socket/fifo artifacts\n\"inputs\": [\"src/**/*\", \"!**/*.sock\", \"!run/**\"]","handlingStrategy":"type-guard","validationCode":"// exclude non-regular files before hashing inputs\nfor entry in walkdir::WalkDir::new(dir) {\n    let e = entry?;\n    let m = e.metadata()?;\n    if !(m.is_file() || m.is_dir()) { continue; } // skip sockets, fifos, devices\n    hash_file(e.path())?;\n}","typeGuard":"fn is_hashable(m: &std::fs::Metadata) -> bool {\n    // uses symlink-free metadata: mirrors validate_file_type in crlf.rs\n    m.is_file() || m.is_dir()\n}","tryCatchPattern":"match hash_path(path) {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput\n        && e.to_string().contains(\"not a regular file\") => { skipped.push(path); continue; }\n    r => r?,\n}","preventionTips":["Keep *.sock / FIFO artifacts out of workspace dirs hashed by turbo","Scope turbo.json `inputs` to the files tasks actually read","Add pre-commit checks for stray socket files in the repo"],"tags":["cache","hashing","filesystem","unix","fifo-socket"],"backgroundTag":"unsupported-file-type","analyzedSha":"7fe373bc270adb30db3c184c55069f77feb1a6d6","analyzedAt":"2026-08-17T10:46:15.696Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}