coleam00/Archon · warning
Workflow run ${runId} was already resolved and is awaiting r
Error message
Workflow run ${runId} was already resolved and is awaiting resume. What it means
approveWorkflow resolves the approval gate through workflowDb.resolveApprovalGate, a compare-and-swap that atomically commits the resolution plus audit events. If the CAS reports it did not win, another actor already resolved the gate and the run is awaiting resume, so approve throws rather than double-resolving.
Source
Thrown at packages/core/src/operations/workflow-operations.ts:680
`approveWorkflow: unexpected child_workflow gate reached resolution for run ${runId}`
);
default: {
const unreachable: never = approval.type;
throw new Error(`approveWorkflow: unhandled gate type '${String(unreachable)}'`);
}
}
// Compare-and-swap: stamp the resolution AND write the audit events ONLY while
// the gate is still open, all in one transaction. This atomic UPDATE — not the
// isGateResolved read above — is the real arbiter, so a concurrent second
// approve loses here (resolved=false) and throws BEFORE any events/telemetry
// land, eliminating the duplicates (#2113); folding the events into the same
// transaction means a failed event write rolls the resolution back so a retry
// can win the still-open gate (#2146). The run stays 'paused'; resume is
// guarded independently by resumeWorkflowRun's CAS.
const { resolved: won } = await workflowDb.resolveApprovalGate(runId, metadataPayload, events);
if (!won) {
throw new Error(`Workflow run ${runId} was already resolved and is awaiting resume.`);
}
// Won the CAS — resolution + audit events already committed atomically.
// Anonymous telemetry: binary resolution only — no ids/comments/names.
captureApprovalResolved({ resolution: 'approved' });
return {
workflowName: run.workflow_name,
workingPath: run.working_path,
userMessage: run.user_message,
codebaseId: run.codebase_id,
conversationId: run.conversation_id,
type: isInteractiveLoop ? 'interactive_loop' : 'approval_gate',
};
}
/**
* Reject a paused workflow run.
*View on GitHub (pinned to 0773b97458)
Solutions
- Treat this as benign: the gate was decided; check which way it went and wait for the resume.
- Catch the error and treat 'already resolved' as success in idempotent callers.
- Serialize decision commands per run ID (disable the approve button after first click).
- If resume never happens after the win, investigate resumeWorkflowRun's CAS/queue.
Example fix
// before
await approveWorkflow(runId, response);
// after
try {
await approveWorkflow(runId, response);
} catch (e) {
if (!(e as Error).message.includes('already resolved')) throw e;
// benign: gate already decided, awaiting resume
} Defensive patterns
Strategy: try-catch
Validate before calling
if (isGateResolved(run.metadata?.approval)) return; // someone already decided
Type guard
function isGateResolved(a: unknown): boolean {
return !!a && typeof a === 'object' && (a as any).resolved != null;
} Try / catch
try { await approveWorkflow(runId, response); }
catch (e) {
if ((e as Error).message.includes('already resolved')) {
// benign CAS loss: gate decided concurrently; poll for resume
return;
}
throw e;
} Prevention
- Serialize gate decisions: one approver/command channel per run.
- Disable approve/reject controls immediately after the first click.
- Design retry logic to treat 'already resolved' as success.
When it happens
Trigger: Two approve/reject calls race on the same paused run and the loser's resolveApprovalGate returns { resolved: false }; also a retry of an approve that already succeeded.
Common situations: An operator and a bot both approve the same gate; a double-click fires two approve requests; a client retries after a timeout unaware the first request committed.
Related errors
- Workflow run ${run.id} was already ${String(approval.resolve
- Workflow run not found or already terminal (id: ${id})
- Failed to claim write-back apply: ${err.message}
- Cannot reject run with status '${run.status}'. Only paused r
- Run ${run.id} is paused waiting on sub-run ${attention.child
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/f87f1536540e4788.
Report an issue: GitHub.