paperclipai/paperclip · error

Paperclip sandbox proxy socket path is ${pathBytes} bytes, e

Error message

Paperclip sandbox proxy socket path is ${pathBytes} bytes, exceeding the Linux limit of ${UNIX_SOCKET_PATH_MAX_BYTES}: ${socketPath}

What it means

Thrown by assertUnixSocketPathLength when the byte length of the sandbox proxy socket path exceeds UNIX_SOCKET_PATH_MAX_BYTES (107, the Linux limit for AF_UNIX sun_path). The proxy writes proxy.sock inside a temp dir created under /tmp or os.tmpdir(); if that dir is nested too deep, the full socket path can exceed 107 bytes and bind() would fail with ENAMETOOLONG. The assert fails fast with a readable message instead of letting the kernel reject the bind.

Source

Thrown at packages/adapter-utils/src/local-process-sandbox.ts:171

  if (value === "deny" || value === "allowlist") return value;
  throw new Error('networkScope must be "deny" or "allowlist".');
}

export function parseLocalProcessFilesystemScope(value: unknown): "workspace" | null {
  if (value == null || value === "") return null;
  if (value === "workspace") return value;
  throw new Error('filesystemScope must be "workspace".');
}

function isNetworkTargetAllowed(hostname: string, port: string, rules: NetworkAllowlistRule[]): boolean {
  const normalizedHostname = hostname.toLowerCase().replace(/^\[|\]$/g, "");
  return rules.some((rule) => rule.hostname === normalizedHostname && (rule.port === null || rule.port === port));
}

function assertUnixSocketPathLength(socketPath: string): void {
  const pathBytes = Buffer.byteLength(socketPath);
  if (pathBytes > UNIX_SOCKET_PATH_MAX_BYTES) {
    throw new Error(
      `Paperclip sandbox proxy socket path is ${pathBytes} bytes, exceeding the Linux limit of ${UNIX_SOCKET_PATH_MAX_BYTES}: ${socketPath}`,
    );
  }
}

async function createNetworkProxyTempDir(): Promise<string> {
  const candidates = Array.from(new Set(["/tmp", os.tmpdir()]));
  let lastError: unknown;
  for (const baseDir of candidates) {
    try {
      const tempDir = await fs.mkdtemp(path.join(baseDir, NETWORK_PROXY_TEMP_PREFIX));
      try {
        assertUnixSocketPathLength(path.join(tempDir, "proxy.sock"));
        return tempDir;
      } catch (error) {
        await fs.rm(tempDir, { recursive: true, force: true });
        lastError = error;
      }

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Set TMPDIR to a short, top-level directory on the Linux host before spawning the sandbox: export TMPDIR=/tmp.
  2. Move the workspace closer to the filesystem root (e.g. /srv/work instead of /home/longuser/projects/deep/repo).
  3. Confirm the host is Linux; this code path only runs there anyway (see error 326), but a long Linux TMPDIR is the usual culprit.
  4. If you control the runner, configure its ephemeral workspace root to a short path so mkdtemp("/tmp/paperclip-network-sandbox-XXXXXX") + "/proxy.sock" stays well under 107 bytes.

Example fix

// before: long TMPDIR inherited from runner
// TMPDIR=/run/user/1000/actions-runner/_work/long-org-name/long-repo-name/tmp

// after
process.env.TMPDIR = "/tmp";
const target = await buildLocalProcessSandboxSpawnTarget(input);
Defensive patterns

Strategy: validation

Validate before calling

const UNIX_SOCKET_PATH_MAX_BYTES = 107;
function assertSafeSocketBase(baseDir: string): void {
  const candidate = path.join(baseDir, "paperclip-network-sandbox-XXXXXXXX", "proxy.sock");
  if (Buffer.byteLength(candidate) > UNIX_SOCKET_PATH_MAX_BYTES - 8) {
    throw new Error(`TMPDIR too long for sandbox socket: ${baseDir}`);
  }
}

if (process.platform === "linux") {
  const tmp = process.env.TMPDIR ?? "/tmp";
  assertSafeSocketBase(tmp);
}

Try / catch

try {
  return await buildLocalProcessSandboxSpawnTarget(input);
} catch (error) {
  if (error instanceof Error && error.message.includes("exceeding the Linux limit of")) {
    throw new ConfigError("TMPDIR is too deeply nested for the sandbox unix socket. Set TMPDIR=/tmp.", { cause: error });
  }
  throw error;
}

Prevention

When it happens

Trigger: TMPDIR points at a long path (e.g. /run/user/1000/some/very/deep/nested/workspace/paperclip-runner-x), the runner is itself nested under a long worktree path, or the system's mkdtemp prefix plus random suffix pushes the path past 107 bytes. Common in CI runners that use long ephemeral workspace names, container layers, or systemd's PrivateTmp paths.

Common situations: macOS dev boxes forwarded to a Linux docker daemon where TMPDIR inherits a long host path, GitHub Actions runners with deeply nested runner directories, or self-hosted runners under /actions-runner/_work/<org>/<repo>/<deep>. Also seen after a TMPDIR change in container orchestration that mounts /tmp from a long overlay path.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/8b04b2b6d2a9f444. Report an issue: GitHub.