denoland/deno · error

invalid path

Error message

invalid path

What it means

Deno's libuv-compat layer for node pipes (libs/core/uv_compat) connecting a Unix domain socket using a pre-bound fd: the path string is converted to a sockaddr_un by make_sockaddr_un, which rejects empty paths and paths longer than the OS sun_path limit (108 bytes on Linux, 104 on macOS, NUL included) with UV_EINVAL; the connect maps that to ErrorKind::InvalidInput 'invalid path'.

Source

Thrown at libs/core/uv_compat/pipe.rs:782

      .internal_fd
      .take()
      .map(|fd| std::os::unix::net::UnixStream::from_raw_fd(fd))
  };
  let raw_fd = bound_stream.as_ref().map(|stream| {
    use std::os::unix::io::AsRawFd;
    stream.as_raw_fd()
  });
  let future = Box::pin(async move {
    if let Some(stream) = bound_stream {
      use std::os::unix::io::AsRawFd;

      let fd = stream.as_raw_fd();
      // Non-blocking connect on the pre-bound socket.
      // SAFETY: fd is a valid socket from uv_pipe_bind.
      unsafe {
        let (addr, addr_len) =
          make_sockaddr_un(path.as_str()).map_err(|_| {
            std::io::Error::new(
              std::io::ErrorKind::InvalidInput,
              "invalid path",
            )
          })?;

        // Set non-blocking before connect.
        let flags = libc::fcntl(fd, libc::F_GETFL);
        if flags != -1 {
          libc::fcntl(fd, libc::F_SETFL, flags | libc::O_NONBLOCK);
        }

        let ret = libc::connect(
          fd,
          &addr as *const _ as *const libc::sockaddr,
          addr_len as libc::socklen_t,
        );
        if ret != 0 {
          let err = std::io::Error::last_os_error();

View on GitHub (pinned to 98f9507aff)

Solutions

  1. Shorten the socket path: place it directly in /tmp or a short per-user dir (e.g. /tmp/myapp.sock).
  2. Derive the path from a short stable hash instead of full identifiers: /tmp/app-<8-char-hash>.sock.
  3. Guard the length before connecting and fail with a clear message (empty check + ~104/108-byte limit depending on platform).
  4. On Linux only, abstract namespace sockets (leading NUL) avoid the path-length limit entirely.

Example fix

// before
const sockPath = `${projectRoot}/.cache/sockets/run-${Date.now()}.sock`; // > 104 bytes on macOS
const s = net.connect(sockPath);

// after
import { createHash } from "node:crypto";
const maxLen = process.platform === "darwin" ? 103 : 107;
const sockPath = `/tmp/app-${createHash("sha1").update(projectRoot).digest("hex").slice(0, 8)}.sock`;
if (sockPath.length === 0 || sockPath.length > maxLen) throw new Error(`socket path invalid (len ${sockPath.length})`);
const s = net.connect(sockPath);
Defensive patterns

Strategy: validation

Validate before calling

function assertSocketPath(p) {
  if (p.length === 0) throw new Error("unix socket path is empty");
  const max = process.platform === "darwin" ? 104 : 108; // sun_path incl. NUL
  if (p.length + 1 > max) throw new Error(`unix socket path too long (${p.length} > ${max - 1}): ${p}`);
}

Type guard

const isValidUnixSocketPath = (p: string): p is `${string}.sock` => p.length > 0 && p.length < (process.platform === "darwin" ? 104 : 108);

Try / catch

try { net.connect(sockPath); } catch (e) { if (/invalid path/.test(String(e))) throw new Error(`socket path invalid/too long (${sockPath.length} chars) — use a shorter path under /tmp`); throw e; }

Prevention

When it happens

Trigger: Connecting a pipe/unix socket through the node-compat layer with an empty path string, or a filesystem path whose length reaches the sun_path limit — deeply nested project dirs, long TMPDIR prefixes (macOS /var/folders/...), or hashed cache paths baked by npm tooling.

Common situations: Unix-socket-based dev tools (IDE language servers, daemon sockets, test runners) run from deeply nested or temp locations; macOS default TMPDIR plus long generated names exceeding 103 usable bytes; embedded/anonymous socket misuse with empty strings.

Related errors


AI-assisted analysis of denoland/deno@98f9507aff (2026-08-20). Data as JSON: /api/errors/1220d0eb0eb27ae6. Report an issue: GitHub.