facebook/flow · error
fd_of_path: open({:?}): {}
Error message
fd_of_path: open({:?}): {} What it means
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.
Source
Thrown at rust_port/crates/flow_daemon/src/daemon.rs:358
// `Daemon.fd_of_path` in OCaml returns a `Unix.file_descr`. We return a
// `std::fs::File` instead: it is the cross-platform Rust analogue (works on
// both Unix and Windows), is convertible to `Stdio` via `Stdio::from(File)`
// on every platform, and avoids the Unix-only `OwnedFd`.
pub fn fd_of_path(path: &Path) -> File {
sys_utils::with_umask(0o111, || {
if let Some(parent) = path.parent()
&& !parent.as_os_str().is_empty()
{
sys_utils::mkdir_no_fail(parent)
.unwrap_or_else(|e| panic!("fd_of_path: mkdir_no_fail({:?}): {}", parent, e));
}
std::fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(path)
.unwrap_or_else(|e| panic!("fd_of_path: open({:?}): {}", path, e))
})
}
pub fn null_fd() -> File {
fd_of_path(Path::new(sys_utils::null_path()))
}
// `StdioFd` lets callers either inherit one of the parent's standard streams
// (matching OCaml's `if stdin <> Unix.stdin then close_if_open stdin` at lines
// 207-213, where passing `Unix.stdin` means "inherit") or pass an owned file
// that should be closed on the parent side after the spawn completes. We use
// `std::fs::File` rather than `OwnedFd` because `OwnedFd` is Unix-only;
// `File` is cross-platform and `Stdio::from(File)` exists on both Unix and
// Windows, so spawn behaves identically on every platform.
pub enum StdioFd {
Inherit,
Owned(File),
}View on GitHub (pinned to f88ac94bcf)
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
Example fix
# before mkdir -p "$TMPDIR"/flow/stdout.log # a DIRECTORY where a file is expected flow start # panics: fd_of_path: open(...): Is a directory # after rm -rf "$TMPDIR"/flow flow start
Defensive patterns
Strategy: validation
Validate before calling
# before starting the daemon: target paths must be files (or absent), parents writable for f in "$TMPDIR"/flow/*.log; do [ -e "$f" ] && [ ! -f "$f" ] && echo "BLOCKED: $f is not a regular file" done
Prevention
- 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
When it happens
Trigger: 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.
Common situations: Leftover directories where flow expects log files; tmp cleaners (systemd-tmpfiles) chowning/relocking files; read-only container layers; Windows long-path issues.
Related errors
- fd_of_path: mkdir_no_fail({:?}): {}
- mkdirp: mkdir {} failed: {}
- Failed to open log file '{}': {}
- failed to create {}: {}
- mkdir_no_fail({:?}): {}
AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20).
Data as JSON: /api/errors/e469f9811496e49f.
Report an issue: GitHub.