coleam00/Archon · error
Failed to signal workflow wait: ${err.message}
Error message
Failed to signal workflow wait: ${err.message} What it means
Thrown by signalWorkflowWait when the database work behind recording an event-wait signal fails. After the event/non-event guard passes, the function runs a conditional UPDATE to atomically record the signal payload in metadata.wait; any driver/SQL failure is logged as `db.workflow_wait_signal_failed` (with runId and event) and rethrown with this message. `{signaled:false}` is returned when the paused row does not match — only an actual DB failure throws.
Source
Thrown at packages/core/src/db/workflows.ts:1701
await insertWorkflowEvent(query, {
workflow_run_id: id,
event_type: 'wait_signaled',
step_name: workflowWaitStepName(parsedWaitContext),
data: {
event: parsedWaitContext.event,
...(payload !== undefined ? { payload } : {}),
},
});
}
return { signaled };
});
} catch (error) {
const err = error as Error;
getLog().error(
{ err, workflowRunId: id, event: parsedWaitContext.event },
'db.workflow_wait_signal_failed'
);
throw new Error(`Failed to signal workflow wait: ${err.message}`);
}
}
/**
* Atomically CLAIM the container write-back apply before the live root is mutated
* (R2-F4). A conditional UPDATE that sets `metadata.writeback_apply_claimed = true`
* only while it is unset — so exactly one resume wins the claim. Returns whether
* THIS caller won. The caller must apply the overlay only on `claimed === true`, and
* on apply FAILURE release the claim (`releaseWritebackClaim`) so a `workflow resume`
* can retry; on a crash AFTER a successful apply the claim stays set, so the next
* resume finds it claimed and does NOT re-apply (no path applies twice).
*/
export async function claimWriteback(id: string): Promise<{ claimed: boolean }> {
const dialect = getDialect();
const extract =
getDatabaseType() === 'postgresql'
? "metadata->>'writeback_apply_claimed'"
: "json_extract(metadata, '$.writeback_apply_claimed')";View on GitHub (pinned to 0773b97458)
Solutions
- Check the `db.workflow_wait_signal_failed` log entry for the underlying driver error
- Verify DB connectivity and retry the signal — recording is atomic and safe to re-issue
- Confirm metadata.wait JSON on the run row is valid and the configured dialect matches the schema
- If signaled:false repeatedly, confirm the run is still status='paused' with the exact wait.event/nodeId
Example fix
// before
await signalWorkflowWait(runId, waitCtx, payload); // throws on DB failure
// after
const { signaled } = await signalWorkflowWait(runId, waitCtx, payload);
if (!signaled) throw new Error(`run ${runId} has no matching paused event wait`); Defensive patterns
Strategy: try-catch
Validate before calling
// confirm there is a matching paused event wait first const run = await getWorkflowRun(id); const wait = run?.metadata?.wait; const signalable = run?.status === 'paused' && wait?.kind === 'event' && wait.event === waitContext.event;
Type guard
function isSignalableEventRun(run: WorkflowRun | undefined, ctx: Extract<WorkflowWaitContext, { kind: 'event' }>): boolean {
const w = run?.metadata?.wait;
return run?.status === 'paused' && w?.kind === 'event' && w.event === ctx.event && w.nodeId === ctx.nodeId;
} Try / catch
try {
const { signaled } = await signalWorkflowWait(id, waitContext, payload);
if (!signaled) log.warn({ id }, 'no matching paused event wait for signal');
} catch (error) {
log.error({ id, err: error }, 'signal failed at DB layer');
throw error;
} Prevention
- Retry signals idempotently — recording is atomic and safe to re-issue
- Keep the run paused until the signal is confirmed
- Preserve metadata.wait structure; do not hand-edit run JSON
- Monitor `db.workflow_wait_signal_failed` for webhook-signaling reliability
When it happens
Trigger: Calling signalWorkflowWait for a paused event wait when the connection fails, the metadata UPDATE errors (JSON path invalid for dialect, lock contention, schema mismatch), or payload serialization fails at the driver.
Common situations: Signaling from a webhook handler while the DB is briefly unavailable; corrupted metadata JSON on the run row; mismatched database type configuration breaking the JSON extraction expressions.
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 get workflow run: ${err.message}
- Workflow run '${runId}' references codebase '${codebaseId}',
- Failed to load codebase '${codebaseId}' for workflow run '${
- Failed to complete workflow run: ${err.message}
- Workflow run not found or not in running state (id: ${id})
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/37c775407e76558a.
Report an issue: GitHub.