{"record":{"id":"e469f9811496e49f","repo":"facebook/flow","slug":"fd-of-path-open","errorCode":null,"errorMessage":"fd_of_path: open({:?}): {}","messagePattern":"fd_of_path: open\\((.+?)\\): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_daemon/src/daemon.rs","lineNumber":358,"sourceCode":"// `Daemon.fd_of_path` in OCaml returns a `Unix.file_descr`. We return a\n// `std::fs::File` instead: it is the cross-platform Rust analogue (works on\n// both Unix and Windows), is convertible to `Stdio` via `Stdio::from(File)`\n// on every platform, and avoids the Unix-only `OwnedFd`.\npub fn fd_of_path(path: &Path) -> File {\n    sys_utils::with_umask(0o111, || {\n        if let Some(parent) = path.parent()\n            && !parent.as_os_str().is_empty()\n        {\n            sys_utils::mkdir_no_fail(parent)\n                .unwrap_or_else(|e| panic!(\"fd_of_path: mkdir_no_fail({:?}): {}\", parent, e));\n        }\n        std::fs::OpenOptions::new()\n            .read(true)\n            .write(true)\n            .create(true)\n            .truncate(true)\n            .open(path)\n            .unwrap_or_else(|e| panic!(\"fd_of_path: open({:?}): {}\", path, e))\n    })\n}\n\npub fn null_fd() -> File {\n    fd_of_path(Path::new(sys_utils::null_path()))\n}\n\n// `StdioFd` lets callers either inherit one of the parent's standard streams\n// (matching OCaml's `if stdin <> Unix.stdin then close_if_open stdin` at lines\n// 207-213, where passing `Unix.stdin` means \"inherit\") or pass an owned file\n// that should be closed on the parent side after the spawn completes. We use\n// `std::fs::File` rather than `OwnedFd` because `OwnedFd` is Unix-only;\n// `File` is cross-platform and `Stdio::from(File)` exists on both Unix and\n// Windows, so spawn behaves identically on every platform.\npub enum StdioFd {\n    Inherit,\n    Owned(File),\n}","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_daemon/src/daemon.rs#L340-L376","documentation":"After the parent directories exist, fd_of_path opens the target file with read+write+create+truncate to obtain the daemon's stdio fd; failure panics with the path and OS error. The parent was just created, so typical causes are EACCES on the final component, a directory existing at the file path, ENAMETOOLONG, EROFS, or ENOSPC.","triggerScenarios":"Opening the daemon's redirect/log file where the final path is a directory, the file exists with permissions that deny the current user, path length exceeds limits, or the volume is read-only/full.","commonSituations":"Leftover directories where flow expects log files; tmp cleaners (systemd-tmpfiles) chowning/relocking files; read-only container layers; Windows long-path issues.","solutions":["Remove the directory or unwritable file occupying the reported path and retry","chmod/chown the target so the current user can open it read-write","Move TMPDIR to a short, writable path","Fix the read-only mount or free space on the volume"],"exampleFix":"# before\nmkdir -p \"$TMPDIR\"/flow/stdout.log   # a DIRECTORY where a file is expected\nflow start                          # panics: fd_of_path: open(...): Is a directory\n\n# after\nrm -rf \"$TMPDIR\"/flow\nflow start","handlingStrategy":"validation","validationCode":"# before starting the daemon: target paths must be files (or absent), parents writable\nfor f in \"$TMPDIR\"/flow/*.log; do\n  [ -e \"$f\" ] && [ ! -f \"$f\" ] && echo \"BLOCKED: $f is not a regular file\"\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never create directories where flow expects its redirect/log files","Make sure temp cleaners do not lock or chown flow's files to other users","Keep daemon file paths short and on writable local storage"],"tags":["daemon","filesystem","file-open","permissions","tmpdir"],"backgroundTag":"file-open-permission-denied","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}