paperclipai/paperclip · error
run coordinator reproduced a result before the run recorded…
Error message
run coordinator reproduced a result before the run recorded one
What it means
Internal invariant violation in the acpx run-coordinator settlement path: the coordinator produced (reproduced) a final turn result while the run's event ledger had not yet recorded any result — results may only be reproduced from an already-recorded entry. This is a fail-fast ordering bug detector (settlement/sync-back racing ahead of the run record), not an expected operational condition; hitting it indicates coordinator state-machine corruption.
Solutions
- Inspect the settlement sequence: the settle() path must read the warm entry only after the run recorded its result.
- Check for a code path that calls result reproduction before appendRunEvent/record of the result (ordering regression).
- Capture the run's heartbeat_run_events ledger to confirm no result row exists and report the ordering bug with the trace.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at packages/adapter-utils/src/acpx-engine/execute.ts:5348 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/59c6d4d3e6cb8d14.
Report an issue: GitHub.
Appendix: source
Thrown at packages/adapter-utils/src/acpx-engine/execute.ts:5348
recordDisposition: recordDispositionReport,
// The settlement sequence is the one live cleanup owner. It claims the
// ledger, releases every settled resource, and returns the final
// disposition report. The child stderr flushes after the sync-back on every
// settled exit path (it stays null before the run reads the warm entry).
settle: async (reason: SettlementReason) => {
const cause: SettlementCause | null =
reason.kind === "pre_turn"
? reason.cause
: reason.completion.kind === "finalized"
? null
: reason.completion.cause;
const report = await settleAcpRun(runResourceLedger, cause, settlementSteps);
recordDispositionReport(report);
if (childStderrState) flushChildStderr(childStderrState);
},
reproduceResult: async (): Promise<AdapterExecutionResult> => {
if (!capturedResult) {
throw new Error("run coordinator reproduced a result before the run recorded one");
}
clearTimeout(stopTimer);
let providerExited = false;
const providerPid = processIdentitySink?.latest?.pid;
if (ctx.signal?.aborted && providerPid && !prepared.processSessionBridge) {
for (let attempt = 0; attempt < 40; attempt += 1) {
providerExited = capturedProcessExited(processIdentitySink.localProcess);
if (providerExited || !forcedStop) break;
await new Promise((resolve) => setTimeout(resolve, 25));
}
}
// A forced process exit can reject ACP close after the OS has already
// confirmed termination. Acknowledge Stop, but never grant replay.
if (ctx.signal?.aborted && providerExited && (runtimeStopConfirmed || forcedStop)) {
capturedResult = {
...capturedResult,
...(safeInterruptedSession && !forcedStop && !("workspaceRestoreFailure" in workspaceRestoreFailureField)
? { executionRecovery: { kind: "interrupted", providerStopped: true, sessionPreserved: true, actionOutcomes: "settled" },View on GitHub (pinned to 3f1d897a7c)