{"record":{"id":"365855238f348336","repo":"paperclipai/paperclip","slug":"persisted-codex-acpx-session-identity-is-inconsist","errorCode":null,"errorMessage":"persisted Codex ACPX session identity is inconsistent","messagePattern":"persisted Codex ACPX session identity is inconsistent","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/acpx/codex-acpx-driver.ts","lineNumber":1881,"sourceCode":"    ![\n      identity.normalizedSessionId,\n      identity.acpxRecordId,\n      identity.backendSessionId,\n      identity.agentSessionId,\n      identity.requestedModel,\n      identity.effectiveModel,\n    ].every(boundedIdentity) ||\n    !/^sha256:[a-f0-9]{64}$/.test(identity.profileDigest) ||\n    !/^sha256:[a-f0-9]{64}$/.test(identity.workspaceDigest) ||\n    (identity.permissionMode !== undefined &&\n      ![\"approve-all\", \"approve-reads\", \"deny-all\"].includes(\n        identity.permissionMode,\n      )) ||\n    !validProviderLifetimeFenceCandidates(\n      identity.providerLifetimeFenceCandidates,\n    )\n  ) {\n    throw new Error(\"persisted Codex ACPX session identity is inconsistent\");\n  }\n  if (\n    snapshot.providerRecoveryPolicy !== undefined &&\n    snapshot.providerRecoveryPolicy !== \"same_session_only\"\n  ) {\n    throw new Error(\"persisted Codex ACPX recovery policy is unsupported\");\n  }\n  if (\n    (snapshot.pendingRuntimeRequests?.length ?? 0) > 0 ||\n    (snapshot.lineage?.length ?? 0) > 0 ||\n    snapshot.goal != null\n  ) {\n    throw new Error(\"persisted Codex ACPX snapshot has unsupported state\");\n  }\n  if (\n    snapshot.lastSourceSequence !== undefined &&\n    (!Number.isSafeInteger(snapshot.lastSourceSequence) ||\n      snapshot.lastSourceSequence < 0)","sourceCodeStart":1863,"sourceCodeEnd":1899,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/acpx/codex-acpx-driver.ts#L1863-L1899","documentation":"When restoring a persisted Codex ACPX session snapshot, the driver validates the persisted identity: permission mode must match an allowed value and the provider lifetime fence candidates must pass validity checks. If either validation fails, the persisted identity is deemed inconsistent and the driver refuses to resume rather than continue with a corrupt or tampered snapshot.","triggerScenarios":"Resuming from a snapshot whose identity.permissionMode is not a recognized mode, or whose providerLifetimeFenceCandidates array is malformed/invalid (wrong shape, stale, or inconsistent entries).","commonSituations":"Snapshots written by an older driver version then read by a newer version with stricter validation; manually edited or truncated persistence files; partial writes during a crash corrupting identity fields.","solutions":["Delete the persisted session snapshot and start a fresh Codex session instead of resuming.","Regenerate the snapshot with the current driver version so identity fields match the current schema.","If snapshots come from an older release, run the migration path or upgrade both writer and reader to compatible versions.","Validate snapshot identity (permissionMode, fence candidates) at write time to avoid persisting inconsistent data."],"exampleFix":"// before\nconst session = await driver.resumeSession(snapshot); // snapshot written by v0 old driver\n// after\nawait fs.rm(snapshotPath);\nconst session = await driver.openSession(); // fresh session, consistent identity","handlingStrategy":"try-catch","validationCode":"function snapshotIdentityLooksValid(snapshot) {\n  return snapshot?.identity?.permissionMode != null &&\n    Array.isArray(snapshot.identity.providerLifetimeFenceCandidates);\n}\nif (!snapshotIdentityLooksValid(snapshot)) freshStart = true;","typeGuard":"function hasConsistentIdentity(s) {\n  return typeof s?.identity?.permissionMode === \"string\" &&\n    Array.isArray(s.identity.providerLifetimeFenceCandidates);\n}","tryCatchPattern":"try {\n  await driver.resumeSession(snapshot);\n} catch (err) {\n  if (err.message === \"persisted Codex ACPX session identity is inconsistent\") {\n    await driver.openSession(); // fresh session fallback\n  } else throw err;\n}","preventionTips":["Write snapshots atomically (temp file + rename) to avoid partial identity records.","Validate identity fields at write time with the shared validator.","Keep writer/reader driver versions compatible; migrate old snapshots."],"tags":["persistence","validation","codex","acpx"],"backgroundTag":"internal-invariant-violation","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"}