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

  1. Inspect the settlement sequence: the settle() path must read the warm entry only after the run recorded its result.
  2. Check for a code path that calls result reproduction before appendRunEvent/record of the result (ordering regression).
  3. 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)