{"record":{"id":"db2dbed68aa6829d","repo":"paperclipai/paperclip","slug":"acpx-provider-package-ancestry-is-invalid","errorCode":null,"errorMessage":"ACPX provider package ancestry is invalid","messagePattern":"ACPX provider package ancestry is invalid","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/acpx/installation-integrity.ts","lineNumber":1683,"sourceCode":"    'const { dirname, extname, join, normalize, relative, resolve } = require(\"node:path\");',\n    'const { fileURLToPath, pathToFileURL } = require(\"node:url\");',\n    \"const commandDirectory = process.argv[1];\",\n    \"const commandName = process.argv[2];\",\n    \"const dependencyAncestorCount = Number.parseInt(process.argv[3], 10);\",\n    \"const serverDependencyAncestorCount = Number.parseInt(process.argv[4], 10);\",\n    \"const serverPackageFormat = process.argv[5];\",\n    \"const dependencyAncestorFormats = JSON.parse(process.argv[6]);\",\n    \"const providerRuntimeExecutableCount = Number.parseInt(process.argv[7], 10);\",\n    `const providerRuntimeEnvironmentVariable = process.env.${VERIFIED_PROVIDER_RUNTIME_TARGET_ENV};`,\n    `delete process.env.${VERIFIED_PROVIDER_RUNTIME_TARGET_ENV};`,\n    `const snapshotHandoff = process.platform === \"darwin\" ? JSON.parse(process.env.${ACPX_PRIVATE_SNAPSHOT_ENV} || \"null\") : null;`,\n    'let privateSnapshot = null; if (snapshotHandoff) { const manifest = fs.readFileSync(snapshotHandoff.path); if (require(\"node:crypto\").createHash(\"sha256\").update(manifest).digest(\"hex\") !== snapshotHandoff.digest) throw new Error(\"ACPX snapshot manifest digest mismatch\"); privateSnapshot = JSON.parse(manifest); }',\n    `delete process.env.${ACPX_PRIVATE_SNAPSHOT_ENV};`,\n    'if (process.platform !== \"linux\" && !(process.platform === \"darwin\" && privateSnapshot && Array.isArray(privateSnapshot.roots) && privateSnapshot.roots.length === dependencyAncestorCount + 1)) throw new Error(\"ACPX provider requires verified package snapshots\");',\n    'const verifySnapshotBytes = (path, bytes) => { if (privateSnapshot && require(\"node:crypto\").createHash(\"sha256\").update(bytes).digest(\"hex\") !== privateSnapshot.digests[path]) throw new Error(\"ACPX private snapshot digest mismatch\"); };',\n    'if (privateSnapshot && providerRuntimeExecutableCount === 1) verifySnapshotBytes(privateSnapshot.executable, fs.readFileSync(privateSnapshot.executable));',\n    `if (!Number.isSafeInteger(dependencyAncestorCount) || dependencyAncestorCount < 0 || dependencyAncestorCount > ${MAX_DEPENDENCY_ANCESTORS}) throw new Error(\"ACPX provider dependency ancestry is invalid\");`,\n    'if (!Number.isSafeInteger(serverDependencyAncestorCount) || serverDependencyAncestorCount < 0 || serverDependencyAncestorCount > dependencyAncestorCount) throw new Error(\"ACPX provider package ancestry is invalid\");',\n    'if ((serverPackageFormat !== \"module\" && serverPackageFormat !== \"commonjs\") || !Array.isArray(dependencyAncestorFormats) || dependencyAncestorFormats.length !== dependencyAncestorCount || dependencyAncestorFormats.some((value) => value !== \"module\" && value !== \"commonjs\")) throw new Error(\"ACPX provider package formats are invalid\");',\n    'if (providerRuntimeExecutableCount !== 0 && providerRuntimeExecutableCount !== 1) throw new Error(\"ACPX provider runtime executable count is invalid\");',\n    `const providerRuntimeExecutableFd = ${DEPENDENCY_ANCESTOR_FD_START} + dependencyAncestorCount;`,\n    'if (providerRuntimeExecutableCount === 1) { if (providerRuntimeEnvironmentVariable !== \"CODEX_PATH\" && providerRuntimeEnvironmentVariable !== \"CLAUDE_CODE_EXECUTABLE\") throw new Error(\"ACPX provider runtime environment target is invalid\"); fs.fstatSync(providerRuntimeExecutableFd); process.env[providerRuntimeEnvironmentVariable] = privateSnapshot ? privateSnapshot.executable : \"/proc/\" + process.pid + \"/fd/\" + providerRuntimeExecutableFd; } else if (providerRuntimeEnvironmentVariable !== undefined) throw new Error(\"ACPX provider runtime environment target is unexpected\");',\n    ...(guarded\n      ? [\n          `const guardianFd = ${DEPENDENCY_ANCESTOR_FD_START} + dependencyAncestorCount + providerRuntimeExecutableCount;`,\n          'const guardian = fs.createReadStream(\"\", { fd: guardianFd, autoClose: false });',\n          `const reapCurrentProviderProcessGroup = ${reapCurrentProviderProcessGroup.toString()};`,\n          \"const killProviderProcess = process.kill.bind(process);\",\n          \"const providerProcessId = process.pid;\",\n          \"const exitProviderProcess = process.exit.bind(process);\",\n          \"let guardianLost = false;\",\n          \"const reapOnGuardianLoss = () => { if (guardianLost) return; guardianLost = true; reapCurrentProviderProcessGroup(killProviderProcess, providerProcessId, exitProviderProcess); };\",\n          'guardian.once(\"end\", reapOnGuardianLoss);',\n          'guardian.once(\"error\", reapOnGuardianLoss);',\n          \"guardian.resume();\",\n          \"fs.fstatSync(guardianFd + 1);\",","sourceCodeStart":1665,"sourceCodeEnd":1701,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/acpx/installation-integrity.ts#L1665-L1701","documentation":"Child-bootstrap validation of the server's dependency ancestor count (serverDependencyAncestorCount). It must be a safe integer within [0, dependencyAncestorCount] — the server's own ancestry is a prefix of the total ancestry loaded through pinned descriptors. This enforces that the server package's module chain is a consistent subset of the verified chain.","triggerScenarios":"The child receives serverDependencyAncestorCount that is not a safe non-negative integer, or a value greater than the total dependencyAncestorCount.","commonSituations":"Manually assembling spawn argv with the count arguments swapped; a wrapper reordering arguments; server/dependency ancestry bookkeeping out of sync after reorganizing module resolution; version mismatch between bootstrap script and caller.","solutions":["Use the library's verified spawn() path so serverDependencyAncestorCount and dependencyAncestorCount are derived together.","Verify argument order: total ancestor count comes before server ancestor count in argv.","Rebuild/reinstall the runner if a stale bootstrap is mismatched with the spawning code.","If constructing both counts, assert serverDependencyAncestorCount <= dependencyAncestorCount before spawn."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!(Number.isSafeInteger(serverDependencyAncestorCount) && serverDependencyAncestorCount >= 0 && serverDependencyAncestorCount <= dependencyAncestors.length)) {\n  throw new Error(\"server ancestor count must be within [0, total ancestor count]\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass counts in the documented argv order (total first, server second)","Derive both counts from the same verified ancestry arrays","Avoid custom spawn wrappers that reorder bootstrap arguments"],"tags":["internal-invariant-violation","process-spawn","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}