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
- 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.
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
- 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.
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
- persisted Codex ACPX session identity is inconsistent
- persisted Codex ACPX resultless recovery requires a complete
- ACPX identity permission mode is invalid
- ACPX provider lifetime fence candidates are invalid
- ACPX provider identity is incomplete
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/1f256f4b0fd98a84.
Report an issue: GitHub.