paperclipai/paperclip · error

persisted Codex ACPX session identity is inconsistent

Error message

persisted Codex ACPX session identity is inconsistent

What it means

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.

Source

Thrown at packages/paperclip-runner/src/drivers/acpx/codex-acpx-driver.ts:1881

    ![
      identity.normalizedSessionId,
      identity.acpxRecordId,
      identity.backendSessionId,
      identity.agentSessionId,
      identity.requestedModel,
      identity.effectiveModel,
    ].every(boundedIdentity) ||
    !/^sha256:[a-f0-9]{64}$/.test(identity.profileDigest) ||
    !/^sha256:[a-f0-9]{64}$/.test(identity.workspaceDigest) ||
    (identity.permissionMode !== undefined &&
      !["approve-all", "approve-reads", "deny-all"].includes(
        identity.permissionMode,
      )) ||
    !validProviderLifetimeFenceCandidates(
      identity.providerLifetimeFenceCandidates,
    )
  ) {
    throw new Error("persisted Codex ACPX session identity is inconsistent");
  }
  if (
    snapshot.providerRecoveryPolicy !== undefined &&
    snapshot.providerRecoveryPolicy !== "same_session_only"
  ) {
    throw new Error("persisted Codex ACPX recovery policy is unsupported");
  }
  if (
    (snapshot.pendingRuntimeRequests?.length ?? 0) > 0 ||
    (snapshot.lineage?.length ?? 0) > 0 ||
    snapshot.goal != null
  ) {
    throw new Error("persisted Codex ACPX snapshot has unsupported state");
  }
  if (
    snapshot.lastSourceSequence !== undefined &&
    (!Number.isSafeInteger(snapshot.lastSourceSequence) ||
      snapshot.lastSourceSequence < 0)

View on GitHub (pinned to 01ad858492)

Solutions

  1. Delete the persisted session snapshot and start a fresh Codex session instead of resuming.
  2. Regenerate the snapshot with the current driver version so identity fields match the current schema.
  3. If snapshots come from an older release, run the migration path or upgrade both writer and reader to compatible versions.
  4. Validate snapshot identity (permissionMode, fence candidates) at write time to avoid persisting inconsistent data.

Example fix

// before
const session = await driver.resumeSession(snapshot); // snapshot written by v0 old driver
// after
await fs.rm(snapshotPath);
const session = await driver.openSession(); // fresh session, consistent identity
Defensive patterns

Strategy: try-catch

Validate before calling

function snapshotIdentityLooksValid(snapshot) {
  return snapshot?.identity?.permissionMode != null &&
    Array.isArray(snapshot.identity.providerLifetimeFenceCandidates);
}
if (!snapshotIdentityLooksValid(snapshot)) freshStart = true;

Type guard

function hasConsistentIdentity(s) {
  return typeof s?.identity?.permissionMode === "string" &&
    Array.isArray(s.identity.providerLifetimeFenceCandidates);
}

Try / catch

try {
  await driver.resumeSession(snapshot);
} catch (err) {
  if (err.message === "persisted Codex ACPX session identity is inconsistent") {
    await driver.openSession(); // fresh session fallback
  } else throw err;
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/365855238f348336. Report an issue: GitHub.