paperclipai/paperclip · error
persisted Codex ACPX resultless recovery requires a complete
Error message
persisted Codex ACPX resultless recovery requires a completed terminal turn
What it means
For a resultless recovery (a Codex ACPX session recovered without a durably settled result), the driver requires that the settlement turn is the session's latest terminal turn and that its fingerprint marks a completed terminal state. This prevents resuming from an incomplete or superseded turn, which could duplicate work or lose results.
Source
Thrown at packages/paperclip-runner/src/drivers/acpx/codex-acpx-driver.ts:2002
)
) {
throw new Error(
"persisted Codex ACPX active turn is not the completed semantic settlement",
);
}
}
} else if (terminalTurns.length > 0) {
const latestTerminalTurnId = terminalTurns.at(-1)!.turnId;
const settlementTurnId = snapshot.activeTurnId ?? latestTerminalTurnId;
const settlement = terminalTurns.find(
(terminal) => terminal.turnId === settlementTurnId,
);
if (
settlementTurnId !== latestTerminalTurnId ||
!settlement ||
!isCompletedTerminal(settlement.fingerprint)
) {
throw new Error(
"persisted Codex ACPX resultless recovery requires a completed terminal turn",
);
}
}
}
function validProviderLifetimeFenceCandidates(
value: unknown,
): value is readonly [number, number, number] {
return (
Array.isArray(value) &&
value.length === 3 &&
value.every(
(port) => Number.isSafeInteger(port) && port >= 49_152 && port <= 65_535,
) &&
new Set(value).size === 3
);
}View on GitHub (pinned to 01ad858492)
Solutions
- Discard the stale snapshot and start a new session/turn rather than recovering an incomplete one.
- Ensure the turn reaches a completed terminal state and its result is settled before the process can be recovered.
- Fix persistence flushing so settlement records are written atomically with terminal turn state.
- If a newer turn exists, re-run recovery logic against the latest terminal turn instead of the old settlement.
Example fix
// before
recoverResultless(snapshot); // settlementTurnId points at superseded turn 7, latest is 9
// after
if (settlementTurnId === latestTerminalTurnId && isCompletedTerminal(settlement.fingerprint)) {
recoverResultless(snapshot);
} else {
await driver.openSession(); // fresh start
} Defensive patterns
Strategy: try-catch
Validate before calling
function canRecoverResultless(snapshot) {
return snapshot.settlementTurnId === snapshot.latestTerminalTurnId &&
snapshot.settlement != null && isCompletedTerminal(snapshot.settlement.fingerprint);
}
if (!canRecoverResultless(snapshot)) planFreshSession = true; Type guard
function hasCompletedSettlement(s) {
return s.settlement != null && isCompletedTerminal(s.settlement.fingerprint) &&
s.settlementTurnId === s.latestTerminalTurnId;
} Try / catch
try {
recoverResultless(snapshot);
} catch (err) {
if (err.message.includes("completed terminal turn")) {
await driver.openSession(); // cannot safely resume
} else throw err;
} Prevention
- Flush settlement records atomically with terminal turn state.
- Never start a new turn before the previous one settles if recovery matters.
- Verify settlementTurnId equals the latest terminal turn before attempting recovery.
When it happens
Trigger: Recovering a resultless session where settlementTurnId !== latestTerminalTurnId, the settlement record is missing, or the settlement fingerprint is not a completed terminal (e.g. aborted/failed/in-progress terminal).
Common situations: Crash mid-turn leaving only a non-completed terminal turn; a later turn superseding the settled one before recovery; persistence truncated so the settlement record is absent while turn IDs exist.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- persisted Codex ACPX session identity is inconsistent
- ACPX provider identity is incomplete
- run.result.proposed
- ACPX_SESSION_ENSURE_NON_ERROR
- ACPX_PERSISTED_SESSION_MISSING
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/a17c70e1694d0177.
Report an issue: GitHub.