paperclipai/paperclip · critical · Error
ACPX snapshot manifest digest mismatch
Error message
ACPX snapshot manifest digest mismatch
What it means
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.
Source
Thrown at packages/paperclip-runner/src/drivers/acpx/installation-integrity.ts:1677
}
function snapshotBootstrap(format: AcpxCommandFormat, guarded = false): string {
return [
'const fs = require("node:fs");',
'const { isBuiltin, registerHooks } = require("node:module");',
'const { dirname, extname, join, normalize, relative, resolve } = require("node:path");',
'const { fileURLToPath, pathToFileURL } = require("node:url");',
"const commandDirectory = process.argv[1];",
"const commandName = process.argv[2];",
"const dependencyAncestorCount = Number.parseInt(process.argv[3], 10);",
"const serverDependencyAncestorCount = Number.parseInt(process.argv[4], 10);",
"const serverPackageFormat = process.argv[5];",
"const dependencyAncestorFormats = JSON.parse(process.argv[6]);",
"const providerRuntimeExecutableCount = Number.parseInt(process.argv[7], 10);",
`const providerRuntimeEnvironmentVariable = process.env.${VERIFIED_PROVIDER_RUNTIME_TARGET_ENV};`,
`delete process.env.${VERIFIED_PROVIDER_RUNTIME_TARGET_ENV};`,
`const snapshotHandoff = process.platform === "darwin" ? JSON.parse(process.env.${ACPX_PRIVATE_SNAPSHOT_ENV} || "null") : null;`,
'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); }',
`delete process.env.${ACPX_PRIVATE_SNAPSHOT_ENV};`,
'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");',
'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"); };',
'if (privateSnapshot && providerRuntimeExecutableCount === 1) verifySnapshotBytes(privateSnapshot.executable, fs.readFileSync(privateSnapshot.executable));',
`if (!Number.isSafeInteger(dependencyAncestorCount) || dependencyAncestorCount < 0 || dependencyAncestorCount > ${MAX_DEPENDENCY_ANCESTORS}) throw new Error("ACPX provider dependency ancestry is invalid");`,
'if (!Number.isSafeInteger(serverDependencyAncestorCount) || serverDependencyAncestorCount < 0 || serverDependencyAncestorCount > dependencyAncestorCount) throw new Error("ACPX provider package ancestry is invalid");',
'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");',
'if (providerRuntimeExecutableCount !== 0 && providerRuntimeExecutableCount !== 1) throw new Error("ACPX provider runtime executable count is invalid");',
`const providerRuntimeExecutableFd = ${DEPENDENCY_ANCESTOR_FD_START} + dependencyAncestorCount;`,
'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");',
...(guarded
? [
`const guardianFd = ${DEPENDENCY_ANCESTOR_FD_START} + dependencyAncestorCount + providerRuntimeExecutableCount;`,
'const guardian = fs.createReadStream("", { fd: guardianFd, autoClose: false });',
`const reapCurrentProviderProcessGroup = ${reapCurrentProviderProcessGroup.toString()};`,
"const killProviderProcess = process.kill.bind(process);",
"const providerProcessId = process.pid;",
"const exitProviderProcess = process.exit.bind(process);",View on GitHub (pinned to 01ad858492)
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.
Defensive patterns
Strategy: retry
Try / catch
try {
await spawnProvider();
} catch (err) {
if (err.message.includes("snapshot manifest digest mismatch")) {
await rebuildPrivateSnapshot(); // regenerate manifest + digest together
await spawnProvider();
} else throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- ACPX private snapshot digest mismatch
- Materialized OpenCode executable digest mismatch
- Public viewer asset differs from trusted build: ${file}
- ACPX ${agent} runtime executable digest mismatch
- ACPX provider requires verified package snapshots
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/0f286c246b17ad0a.
Report an issue: GitHub.