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

  1. Remove the directory or unwritable file occupying the reported path and retry
  2. chmod/chown the target so the current user can open it read-write
  3. Move TMPDIR to a short, writable path
  4. 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

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


AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20). Data as JSON: /api/errors/e469f9811496e49f. Report an issue: GitHub.