{"record":{"id":"0f286c246b17ad0a","repo":"paperclipai/paperclip","slug":"acpx-snapshot-manifest-digest-mismatch","errorCode":null,"errorMessage":"ACPX snapshot manifest digest mismatch","messagePattern":"ACPX snapshot manifest digest mismatch","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/paperclip-runner/src/drivers/acpx/installation-integrity.ts","lineNumber":1677,"sourceCode":"}\n\nfunction snapshotBootstrap(format: AcpxCommandFormat, guarded = false): string {\n  return [\n    'const fs = require(\"node:fs\");',\n    'const { isBuiltin, registerHooks } = require(\"node:module\");',\n    '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);\",","sourceCodeStart":1659,"sourceCodeEnd":1695,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/acpx/installation-integrity.ts#L1659-L1695","documentation":"This error is thrown inside the generated provider bootstrap script that runs in the spawned child process on macOS. The parent passes a private-snapshot handoff (path + expected sha256 digest) via an env var; the child reads the manifest file, hashes it, and compares against the declared digest. A mismatch means the snapshot manifest file changed (or was replaced/corrupted) between parent-side preparation and child-side read — an integrity/TOCTOU guard.","triggerScenarios":"On darwin, the ACPX_PRIVATE_SNAPSHOT_ENV handoff points at a manifest file whose sha256 does not match snapshotHandoff.digest when the guarded child parses it.","commonSituations":"The snapshot directory was modified, cleaned, or re-generated between spawn and child startup; antivirus/indexer or another build process rewrote the file; a stale handoff env var from a previous run pointed at a replaced manifest; disk corruption.","solutions":["Regenerate the private package snapshot (rerun the verification/install step) so the manifest and its recorded digest are rebuilt together.","Ensure no concurrent process (build, watcher, cleaner) writes to the snapshot directory while a provider is being spawned.","Delete stale snapshot artifacts and re-spawn; never reuse handoff data from a previous process run.","Check disk/filesystem health if the mismatch recurs without external modification."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await spawnProvider();\n} catch (err) {\n  if (err.message.includes(\"snapshot manifest digest mismatch\")) {\n    await rebuildPrivateSnapshot(); // regenerate manifest + digest together\n    await spawnProvider();\n  } else throw err;\n}","preventionTips":["Do not write to or clean the snapshot directory while providers run","Regenerate snapshots after any dependency install/upgrade","Never reuse snapshot handoff env data from a previous process run"],"tags":["integrity","checksum","process-spawn","security"],"backgroundTag":"checksum-mismatch","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}