paperclipai/paperclip · error · Error

ACPX ${agent} runtime executable must be a bounded executabl

Error message

ACPX ${agent} runtime executable must be a bounded executable file

What it means

Once the file is open, the runtime fstat's it and requires the executable to be a regular file of nonzero size, no larger than MAX_ACPX_RUNTIME_EXECUTABLE_BYTES, with at least one execute bit set (mode & 0o111). This bounds the hashing work and ensures the file is actually an executable. Any violation of size or mode throws this error.

Source

Thrown at packages/paperclip-runner/src/drivers/acpx/installation-integrity.ts:1051

    handle = await open(
      executablePath,
      verifiedExecutableOpenFlags(process.platform, constants.O_NOFOLLOW),
    );
  } catch {
    throw new Error(
      `ACPX ${agent} runtime executable could not be opened as a no-follow regular file`,
    );
  }

  try {
    const before = await handle.stat({ bigint: true });
    if (
      !before.isFile() ||
      before.size < 1n ||
      before.size > BigInt(MAX_ACPX_RUNTIME_EXECUTABLE_BYTES) ||
      (before.mode & 0o111n) === 0n
    ) {
      throw new Error(
        `ACPX ${agent} runtime executable must be a bounded executable file`,
      );
    }
    const hash = createHash("sha256");
    const buffer = Buffer.alloc(1024 * 1024);
    let position = 0;
    try {
      while (position < Number(before.size)) {
        const { bytesRead } = await handle.read(
          buffer,
          0,
          Math.min(buffer.length, Number(before.size) - position),
          position,
        );
        if (bytesRead === 0) break;
        hash.update(buffer.subarray(0, bytesRead));
        position += bytesRead;
      }

View on GitHub (pinned to 01ad858492)

Solutions

  1. Reinstall or re-download the ACPX runtime so the binary is complete (size > 0 and within the size bound)
  2. Restore the execute bit: `chmod +x <path-to-acpx-binary>`
  3. Verify the file at the configured path is the actual binary, not an archive or payload placed there by mistake
  4. Check the binary size against MAX_ACPX_RUNTIME_EXECUTABLE_BYTES if you ship a custom build
  5. Copy the binary with permission preservation (`cp -p` / `install -m 0755`) instead of a plain copy

Example fix

// before
-rw-r--r-- acpx  # 0 bytes after interrupted download
// after
rm acpx && installer reinstall acpx
chmod +x /opt/acpx/bin/acpx   # -rwxr-xr-x
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from 'node:fs';
function looksLikeExecutable(p: string, maxBytes: number): boolean {
  try {
    const st = statSync(p);
    return st.isFile() && st.size > 0 && st.size <= maxBytes && (st.mode & 0o111) !== 0;
  } catch {
    return false;
  }
}

Try / catch

try {
  await startAcppRuntime();
} catch (e) {
  if (String(e?.message).includes('must be a bounded executable file')) {
    // reinstall or chmod +x the binary, then retry
    await repairAcpxInstallation();
    await startAcppRuntime();
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: fstat via the opened handle returns size 0 (truncated/partial download), size above MAX_ACPX_RUNTIME_EXECUTABLE_BYTES, the opened inode is not a regular file (rare after the open checks), or permission bits have no x bit set (chmod a-x, copied with permissions stripped).

Common situations: Interrupted download/copy left a zero-byte or partial binary; a packaging step stripped the executable bit (git checkout on a filesystem without exec bits, or Windows->Unix copy); someone replaced the binary with a huge blob (e.g. a tarball) at the expected path; a copied binary lacks mode bits.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/2cc58ccc0f60f1fb. Report an issue: GitHub.