paperclipai/paperclip · error

Verified runtime executable descriptor is invalid

Error message

Verified runtime executable descriptor is invalid

What it means

verifiedRuntimeExecutable() reads the PAPERCLIP_VERIFIED_RUNTIME_EXECUTABLE handoff env var to recover the runner-authenticated executable in a descriptor-loaded sidecar. On Linux the value must be a /proc/self/fd/<n> descriptor path; anything else is rejected so an unverified path can never be treated as the verified runtime.

Source

Thrown at packages/paperclip-runner/src/drivers/acpx/verified-runtime-executable.ts:29

/**
 * Recover the runner-authenticated executable inherited by a descriptor-loaded
 * sidecar. Linux descendants must explicitly inherit this descriptor: Node
 * resolves process.execPath and /proc/self/exe to a deleted memfd alias that a
 * later exec cannot reopen.
 */
export function verifiedRuntimeExecutable(
  environment: NodeJS.ProcessEnv = process.env,
  platform: NodeJS.Platform = process.platform,
  _currentPid: number = process.pid,
  fallback: string = process.execPath,
): string {
  const configured = environment[VERIFIED_RUNTIME_EXECUTABLE_ENV];
  if (configured === undefined) return fallback;

  if (platform === "linux") {
    if (/^\/proc\/self\/fd\/[0-9]+$/.test(configured)) return configured;
    throw new Error("Verified runtime executable descriptor is invalid");
  }

  if (platform === "darwin") {
    if (
      !isAbsolute(fallback) ||
      resolve(fallback) !== fallback ||
      configured !== fallback
    ) {
      throw new Error("Verified runtime executable path is invalid");
    }
    // The Rust supervisor materializes the authenticated runtime as a private,
    // read-only executable and starts this process from that exact pathname.
    // Descendants may inherit the handoff variable, but they cannot nominate a
    // different absolute path and have it treated as verified.
    return fallback;
  }

  throw new Error(

View on GitHub (pinned to 01ad858492)

Solutions

  1. Remove PAPERCLIP_VERIFIED_RUNTIME_EXECUTABLE so the fallback (process.execPath) is used when no descriptor handoff occurred
  2. Let the supervisor perform the handoff properly: inherit the fd and set the value to /proc/self/fd/<n>
  3. Do not run the runner under wrappers/scripts that rewrite or re-export the env var
  4. Ensure the source fd referenced by the value actually exists in the child's fd table

Example fix

// before
env.PAPERCLIP_VERIFIED_RUNTIME_EXECUTABLE = "/usr/local/bin/paperclip-runner"; // linux
// after
delete env.PAPERCLIP_VERIFIED_RUNTIME_EXECUTABLE; // use process.execPath fallback
Defensive patterns

Strategy: validation

Validate before calling

const v = process.env.PAPERCLIP_VERIFIED_RUNTIME_EXECUTABLE;
if (v !== undefined && process.platform === "linux" &&
    !/^\/proc\/self\/fd\/[0-9]+$/.test(v)) {
  delete process.env.PAPERCLIP_VERIFIED_RUNTIME_EXECUTABLE; // or fix the value
}

Type guard

function isValidLinuxDescriptor(v) {
  return typeof v === "string" && /^\/proc\/self\/fd\/[0-9]+$/.test(v);
}

Try / catch

try {
  const exe = verifiedRuntimeExecutable();
} catch (err) {
  if (err.message === "Verified runtime executable descriptor is invalid") {
    const { [VERIFIED_RUNTIME_EXECUTABLE_ENV]: _omit, ...clean } = process.env;
    return verifiedRuntimeExecutable(clean);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling verifiedRuntimeExecutable() (directly or via executable) on Linux when the env var is set to a non-descriptor value, e.g. a filesystem path, relative path, or /proc/self/exe, or when the env var was set manually/corrupted by a wrapper script.

Common situations: Manually exporting PAPERCLIP_VERIFIED_RUNTIME_EXECUTABLE when launching the runner outside the Rust supervisor; a shell wrapper rewriting the env value; spawning a Linux child without the fd-passing table the value expects.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


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