xai-org/grok-build · error

unix socket path too long: {}

Error message

unix socket path too long: {}

What it means

connect_unix builds a sockaddr_un and can only store sun_path.len() (108 on Linux) bytes of the socket path. If the socket path is at or beyond that limit, the connection cannot even be attempted, so it bails early with the offending path.

Source

Thrown at crates/codegen/xai-fast-worktree/src/nfs/client.rs:579

pub struct QuerySnapshot {
    pub phase: Option<String>,
    pub declined: Option<String>,
    pub storage_full: bool,
    pub unknown: bool,
    pub mount: Option<MountInfo>,
}

/// `UnixStream::connect` has no deadline. Non-blocking connect + `poll` so a
/// socket that exists but is not accepting cannot hang ping/create/remove.
fn connect_unix(path: &Path, timeout: Duration) -> Result<UnixStream> {
    let bytes = path.as_os_str().as_bytes();
    let max_path = {
        // SAFETY: sockaddr_un is a C POD; zeroed is a valid empty address.
        let z: libc::sockaddr_un = unsafe { std::mem::zeroed() };
        z.sun_path.len()
    };
    if bytes.len() >= max_path {
        anyhow::bail!("unix socket path too long: {}", path.display());
    }

    // SAFETY: AF_UNIX/SOCK_STREAM is a defined socket; the fd is owned below.
    let fd = unsafe { libc::socket(libc::AF_UNIX, libc::SOCK_STREAM, 0) };
    if fd < 0 {
        return Err(std::io::Error::last_os_error()).context("socket");
    }
    // SAFETY: `fd` is a socket we just created and exclusively own.
    let fd = unsafe { OwnedFd::from_raw_fd(fd) };
    let raw = fd.as_raw_fd();
    // SAFETY: `raw` is the live socket from `fd`; F_GETFD/F_SETFD/F_GETFL/F_SETFL
    // on our fd are defined.
    unsafe {
        let fd_flags = libc::fcntl(raw, libc::F_GETFD);
        if fd_flags >= 0 {
            libc::fcntl(raw, libc::F_SETFD, fd_flags | libc::FD_CLOEXEC);
        }
        let fl = libc::fcntl(raw, libc::F_GETFL);

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Shorten the socket path: configure the daemon/client to use a short path like /tmp/grove.sock or a short XDG_RUNTIME_DIR
  2. Reduce nesting depth of the workspace/checkout so the socket path fits under 108 bytes
  3. Set TMPDIR to a short directory (e.g. /tmp/gt) for builds/tests that create the socket
  4. If you control the library, consider socket-dir-based naming or abstract sockets

Example fix

// before
export TMPDIR=/home/very/long/monorepo/path/target/tmp/sockets
// after
export TMPDIR=/tmp/gt   # keeps socket paths well under sun_path (108 bytes)
Defensive patterns

Strategy: validation

Validate before calling

use std::os::unix::ffi::OsStrExt;
fn socket_path_fits(path: &std::path::Path) -> bool {
    path.as_os_str().as_bytes().len() < 108 // sun_path len on Linux
}

Prevention

When it happens

Trigger: Calling client.connect_unix (indirectly via call, or directly in connect_missing_socket_fails_quickly) with a socket path >= ~108 bytes — typically a deeply nested temp/XDG cache directory or long project directory names.

Common situations: Rust target/tmp directories under long monorepo paths pushing the daemon socket over 108 chars; running tests under deeply nested CI workspaces; TMPDIR configured to a very long path.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/ee73efb71f329bdf. Report an issue: GitHub.