{"record":{"id":"1f256f4b0fd98a84","repo":"paperclipai/paperclip","slug":"acpx-persisted-session-missing","errorCode":"ACPX_PERSISTED_SESSION_MISSING","errorMessage":"The pinned ACPX runtime omitted its persisted session record","messagePattern":"The pinned ACPX runtime omitted its persisted session record","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/acpx/codex-runtime-adapter.ts","lineNumber":1243,"sourceCode":"async function* eventsAfterLifetimeOwnership<T>(\n  events: AsyncIterable<T>,\n  ownershipVerified: Promise<void>,\n): AsyncIterable<T> {\n  await ownershipVerified;\n  yield* events;\n}\n\nasync function persistedRuntimeStatus(\n  sessionStore: AcpSessionStore,\n  handle: AcpRuntimeHandle,\n  identity: AcpxRuntimePortIdentity,\n): Promise<AcpxModelStatus> {\n  const recordId = handle.acpxRecordId ?? handle.sessionKey;\n  const record = await sessionStore.load(recordId);\n  if (!record) {\n    throw Object.assign(\n      new Error(\"The pinned ACPX runtime omitted its persisted session record\"),\n      { code: \"ACPX_PERSISTED_SESSION_MISSING\" },\n    );\n  }\n  const persistedAgentSessionId =\n    nonEmptyRuntimeIdentity(record.agentSessionId) ?? record.acpSessionId;\n  if (\n    record.acpxRecordId !== identity.acpxRecordId ||\n    record.acpSessionId !== identity.backendSessionId ||\n    persistedAgentSessionId !== identity.agentSessionId\n  ) {\n    throw Object.assign(\n      new Error(\"The persisted ACPX session identity changed after admission\"),\n      { code: \"ACPX_PERSISTED_SESSION_IDENTITY_MISMATCH\" },\n    );\n  }\n  const currentModelId = record.acpx?.current_model_id;\n  const availableModelIds = record.acpx?.available_models;\n  return {\n    summary: [","sourceCodeStart":1225,"sourceCodeEnd":1261,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/acpx/codex-runtime-adapter.ts#L1225-L1261","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-create the ACPX session (respawn the runtime) so a fresh persisted record is written, then query status.","Verify the sessionStore is the same store the runtime persisted into (same DATABASE_URL/data directory).","Check that handle.acpxRecordId and handle.sessionKey are correct and were not stale handles from a previous run.","If records are being deleted concurrently, audit the cleanup path for premature session-store eviction."],"exampleFix":"// before\nconst status = await port.getStatus(); // throws if record missing\n// after\nconst record = await sessionStore.load(handle.acpxId);\nif (!record) {\n  await respawnAcpxSession(handle); // re-persists the record\n}\nconst status = await port.getStatus();","handlingStrategy":"try-catch","validationCode":"const record = await sessionStore.load(handle.acpxRecordId ?? handle.sessionKey);\nif (!record) {\n  throw new Error(\"ACPX session record missing; respawn the runtime before querying status\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  const status = await port.getStatus();\n} catch (e) {\n  if (e.code === \"ACPX_PERSISTED_SESSION_MISSING\") {\n    await respawnAcpxSession(handle);\n  } else throw e;\n}","preventionTips":["Do not wipe the data directory (data/pglite) while sessions are live.","Verify the runtime persists its session record before the first status query.","Use handles from the same store/database the runtime writes to.","Audit cleanup paths for premature record deletion."],"tags":["record-not-found","persistence","acpx","session-store"],"backgroundTag":"record-not-found","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}