{"record":{"id":"91cc1b3e63c88f3f","repo":"paperclipai/paperclip","slug":"verified-acpx-installation-does-not-match-its-prof","errorCode":null,"errorMessage":"Verified ACPX installation does not match its profile","messagePattern":"Verified ACPX installation does not match its profile","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/acpx/runtime-host.ts","lineNumber":315,"sourceCode":"    if (\n      options.agent !== \"codex\" &&\n      options.managedCodexCredentialSourcePath !== undefined\n    ) {\n      throw new Error(\n        \"Managed Codex credentials require the Codex ACPX profile\",\n      );\n    }\n\n    const installation = await runAbortableAdmissionStage(\n      options.signal,\n      () =>\n        (dependencies.verifyInstallation ?? verifyQualifiedAcpxInstallation)(\n          profile,\n        ),\n      dependencies.retainAdmissionCleanup,\n    );\n    if (installation.commandDigest !== profile.commandDigest) {\n      throw new Error(\"Verified ACPX installation does not match its profile\");\n    }\n    let command: VerifiedAcpxCommandLease | null = null;\n    let credential: AcpxProviderLifetimeLease | null = null;\n    let toolBridge: RunnerToolBridge | null = null;\n    let runtime: AcpxRuntimePort | null = null;\n    let pendingRuntimeOwnsCredential = false;\n    const admissionVerificationTimeoutMs =\n      dependencies.admissionVerificationTimeoutMs ??\n      RUNTIME_ADMISSION_VERIFICATION_TIMEOUT_MS;\n    const admissionCleanupTimeoutMs =\n      dependencies.admissionCleanupTimeoutMs ??\n      RUNTIME_ADMISSION_VERIFICATION_TIMEOUT_MS;\n    let failedAdmissionCleanupTransferred = false;\n    let resolveFailedAdmissionCleanupTransfer!: () => void;\n    const failedAdmissionCleanupTransfer = new Promise<void>((resolve) => {\n      resolveFailedAdmissionCleanupTransfer = resolve;\n    });\n    const retainFailedAdmissionCleanup = (cleanup: Promise<void>): void => {","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/acpx/runtime-host.ts#L297-L333","documentation":"During ACPX runtime host open(), the installation is verified via verifyQualifiedAcpxInstallation (or a dependency override), and the resulting commandDigest is compared against the command digest pinned in the profile. This error means the on-disk/verified ACPX executable differs from the one the profile was built for, so the host refuses to launch an unverified binary.","triggerScenarios":"Calling open() when the ACPX binary on disk changed (upgrade, downgrade, reinstall, PATH change) after the profile recorded its commandDigest, or when verifyInstallation is stubbed/returns a mismatched installation.","commonSituations":"ACPX was auto-updated between profile creation and runtime open; multiple ACPX versions installed and PATH resolves a different one; a cached/stale profile from a previous session; CI images rebuilt with a different toolchain version.","solutions":["Recreate/refresh the ACPX profile so its commandDigest matches the currently installed executable","Pin the ACPX version so upgrades do not occur mid-session and reopen with a matching profile","If a custom dependencies.verifyInstallation is injected, ensure it returns an installation whose commandDigest equals profile.commandDigest","Delete stale runtime/session state referencing the old profile and retry open()"],"exampleFix":"// before\nconst host = await open({ profile: staleProfile });\n// after\nconst profile = await rebuildAcpxProfile(currentInstallation); // digest matches binary\nconst host = await open({ profile });","handlingStrategy":"validation","validationCode":"const installation = await verifyQualifiedAcpxInstallation(profile);\nif (installation.commandDigest !== profile.commandDigest) {\n  throw new Error(\"Profile digest is stale; rebuild profile before open()\");\n}","typeGuard":"function isProfileCurrent(installation, profile) {\n  return installation?.commandDigest === profile?.commandDigest;\n}","tryCatchPattern":"try {\n  const host = await open({ profile });\n} catch (err) {\n  if (err.message === \"Verified ACPX installation does not match its profile\") {\n    const freshProfile = await rebuildAcpxProfile();\n    return open({ profile: freshProfile });\n  }\n  throw err;\n}","preventionTips":["Pin ACPX versions so upgrades never invalidate a live profile","Rebuild the profile whenever the installed binary changes","Never stub verifyInstallation in production paths","Compare digests eagerly before long-running admission work"],"tags":["acpx","runtime","verification","digest-mismatch"],"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"}