paperclipai/paperclip · error

ACPX_PERSISTED_SESSION_MISSING

ACPX_PERSISTED_SESSION_MISSING

Error message

The pinned ACPX runtime omitted its persisted session record

What it means

persistedRuntimeStatus() loads the ACPX session record from the session store using the handle's acpxRecordId (falling back to sessionKey) to compute runtime status from persisted state. If the store returns no record for that id, the pinned runtime failed to persist its session before status was read, so the adapter throws this coded error (ACPX_PERSISTED_SESSION_MISSING). This is an integrity check: status should be derivable from durable state, not in-memory guesses.

Source

Thrown at packages/paperclip-runner/src/drivers/acpx/codex-runtime-adapter.ts:1243

async function* eventsAfterLifetimeOwnership<T>(
  events: AsyncIterable<T>,
  ownershipVerified: Promise<void>,
): AsyncIterable<T> {
  await ownershipVerified;
  yield* events;
}

async function persistedRuntimeStatus(
  sessionStore: AcpSessionStore,
  handle: AcpRuntimeHandle,
  identity: AcpxRuntimePortIdentity,
): Promise<AcpxModelStatus> {
  const recordId = handle.acpxRecordId ?? handle.sessionKey;
  const record = await sessionStore.load(recordId);
  if (!record) {
    throw Object.assign(
      new Error("The pinned ACPX runtime omitted its persisted session record"),
      { code: "ACPX_PERSISTED_SESSION_MISSING" },
    );
  }
  const persistedAgentSessionId =
    nonEmptyRuntimeIdentity(record.agentSessionId) ?? record.acpSessionId;
  if (
    record.acpxRecordId !== identity.acpxRecordId ||
    record.acpSessionId !== identity.backendSessionId ||
    persistedAgentSessionId !== identity.agentSessionId
  ) {
    throw Object.assign(
      new Error("The persisted ACPX session identity changed after admission"),
      { code: "ACPX_PERSISTED_SESSION_IDENTITY_MISMATCH" },
    );
  }
  const currentModelId = record.acpx?.current_model_id;
  const availableModelIds = record.acpx?.available_models;
  return {
    summary: [

View on GitHub (pinned to 01ad858492)

Solutions

  1. Re-create the ACPX session (respawn the runtime) so a fresh persisted record is written, then query status.
  2. Verify the sessionStore is the same store the runtime persisted into (same DATABASE_URL/data directory).
  3. Check that handle.acpxRecordId and handle.sessionKey are correct and were not stale handles from a previous run.
  4. If records are being deleted concurrently, audit the cleanup path for premature session-store eviction.

Example fix

// before
const status = await port.getStatus(); // throws if record missing
// after
const record = await sessionStore.load(handle.acpxId);
if (!record) {
  await respawnAcpxSession(handle); // re-persists the record
}
const status = await port.getStatus();
Defensive patterns

Strategy: try-catch

Validate before calling

const record = await sessionStore.load(handle.acpxRecordId ?? handle.sessionKey);
if (!record) {
  throw new Error("ACPX session record missing; respawn the runtime before querying status");
}

Try / catch

try {
  const status = await port.getStatus();
} catch (e) {
  if (e.code === "ACPX_PERSISTED_SESSION_MISSING") {
    await respawnAcpxSession(handle);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling port.getStatus() (or any path reaching persistedRuntimeStatus) where sessionStore.load(recordId) returns null/undefined because the runtime never wrote the session record or it was deleted.

Common situations: Data directory wiped or reset (e.g. removing data/pglite) while a session handle is still alive; runtime crashed before its first persist; handle.acpxRecordId/sessionKey pointing at a record from a different store; concurrent cleanup deleting the record mid-flight.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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