coleam00/Archon · error
Failed to resume workflow run: ${err.message}
Error message
Failed to resume workflow run: ${err.message} What it means
resumeWorkflowRun performs a compare-and-swap UPDATE that flips a run from failed/paused to an active state; any driver error inside that transaction is logged (db.workflow_run_resume_failed) and rethrown wrapped in this message. Note the same message is reused for the CAS-miss path after the try/catch (see [249] for the probe's own wrapper) — this instance specifically means the resume transaction itself hit a database error, not a status conflict.
Source
Thrown at packages/core/src/db/workflows.ts:991
await insertWorkflowEvent(query, {
workflow_run_id: id,
event_type: 'workflow_resumed',
data: { error: clearedError },
});
}
if (rowCount > 0 && scheduled !== null && triggeredAt !== null) {
await insertWorkflowEvent(query, {
workflow_run_id: id,
event_type: 'quota_resume_triggered',
data: { attempt: scheduled.attempt, resume_at: scheduled.resumeAt },
});
}
return { rowCount };
});
} catch (error) {
const err = error as Error;
getLog().error({ err, workflowRunId: id }, 'db.workflow_run_resume_failed');
throw new Error(`Failed to resume workflow run: ${err.message}`);
}
if (updateResult.rowCount === 0) {
// CAS miss: the row is no longer resumable — deleted, terminal, or already
// activated by another caller. Refuse rather than double-claim the worktree.
// Probe the current status for an actionable error (informational only; the
// probe rethrows on its own failure).
let probeRows: readonly { status: string }[];
try {
const probe = await pool.query<{ status: string }>(
'SELECT status FROM remote_agent_workflow_runs WHERE id = $1',
[id]
);
probeRows = probe.rows;
} catch (error) {
const err = error as Error;
getLog().error({ err, workflowRunId: id }, 'db.workflow_run_resume_probe_failed');
throw new Error(`Failed to resume workflow run: ${err.message}`, { cause: err });View on GitHub (pinned to 0773b97458)
Solutions
- Read the db.workflow_run_resume_failed log for the underlying driver error.
- Retry the resume after transient errors — the CAS design prevents double-claiming, so a retry is safe.
- If the CAS-miss error follows, call again only after checking the run's current status via getWorkflowRunStatus.
- Verify UPDATE permissions on workflow_runs and INSERT permissions on workflow_events.
Example fix
// before
await resumeWorkflowRun(runId, cursor);
// after
try {
await resumeWorkflowRun(runId, cursor);
} catch (err) {
getLog().error({ err, runId }, 'resume_tx_failed');
throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Check the run is still resumable before attempting the CAS resume
const status = await getWorkflowRunStatus(runId);
if (status !== 'paused' && status !== 'failed') {
throw new Error(`run ${runId} is ${status ?? 'missing'}; not resumable`);
} Type guard
function isResumeTxError(err: unknown): err is Error & { cause?: unknown } {
return err instanceof Error && err.message.startsWith('Failed to resume workflow run:');
} Try / catch
try {
const result = await resumeWorkflowRun(runId, cursor);
} catch (err) {
// Driver error inside the resume transaction; rollback already happened — retry is safe.
if (isTransient(err)) return retryResume(runId, cursor);
throw err;
} Prevention
- Rely on the CAS: a retry after failure cannot double-claim the worktree.
- Serialize admin actions and user resumes on the same run where possible.
- Verify UPDATE/INSERT grants after DB role changes.
- Watch db.workflow_run_resume_failed logs for deadlock patterns.
When it happens
Trigger: Calling resumeWorkflowRun(id, cursor) when the UPDATE/INSERTs inside the transaction fail: connection dropped mid-transaction, deadlock with another resume attempt, constraint violation on inserted events, or insufficient UPDATE privileges.
Common situations: Two operators (or the scheduler and a user) resuming the same run concurrently causing lock contention; DB failover mid-transaction; workflow_events insert blocked by schema drift.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Failed to cancel resumable runs for conversation: ${err.mess
- Failed to find resumable run: ${err.message}
- Failed to find resumable run by parent conversation: ${err.m
- Failed to pause workflow run for wait: ${err.message}
- Failed to clear workflow wait: ${err.message}
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/d2c470caaafd3e6c.
Report an issue: GitHub.