{"record":{"id":"68e00b84041fcf70","repo":"coleam00/Archon","slug":"failed-to-pause-workflow-run-err-message","errorCode":null,"errorMessage":"Failed to pause workflow run: ${err.message}","messagePattern":"Failed to pause workflow run: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/db/workflows.ts","lineNumber":1433,"sourceCode":"        id,\n        // Caller-supplied run-level metadata (e.g. `pending_writeback`) rides the SAME\n        // atomic write so there is no window where the run is paused without it (M3).\n        JSON.stringify(extraMetadata ?? {}),\n        // The complete gate context. JSON.stringify drops undefined, and the write\n        // replaces rather than merges, so an optional field the caller left unset is\n        // simply absent — no explicit-null reset list to keep in sync.\n        JSON.stringify(approvalContext),\n      ]\n    );\n    if (result.rowCount === 0) {\n      getLog().warn({ workflowRunId: id }, 'db.workflow_run_pause_no_match');\n      throw new Error(`Workflow run not found or not in running state (id: ${id})`);\n    }\n  } catch (error) {\n    if (error instanceof Error && error.message.startsWith('Workflow run not found')) throw error;\n    const err = error as Error;\n    getLog().error({ err, workflowRunId: id }, 'db.workflow_run_pause_failed');\n    throw new Error(`Failed to pause workflow run: ${err.message}`);\n  }\n}\n\n/** Pause a running run on a persisted time/event condition. */\nexport async function pauseWorkflowRunForWait(\n  id: string,\n  waitContext: WorkflowWaitContext,\n  pause: WorkflowWaitPause\n): Promise<void> {\n  const parsedWaitContext = workflowWaitContextSchema.parse(waitContext);\n  try {\n    await getDatabase().withTransaction(async query => {\n      const result = await query(\n        `UPDATE remote_agent_workflow_runs\n         SET status = 'paused', metadata = ${replaceWaitMetadata(2)}\n         WHERE id = $1 AND status = 'running'`,\n        [id, JSON.stringify(parsedWaitContext)]\n      );","sourceCodeStart":1415,"sourceCodeEnd":1451,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/core/src/db/workflows.ts#L1415-L1451","documentation":"This is the wrap-around error for unexpected database failures while pausing a workflow run. The pause function re-throws the intentional 'Workflow run not found or not in running state' error unchanged, but any other error (connection loss, SQL failure, serialization error) is logged as db.workflow_run_pause_failed and re-thrown as 'Failed to pause workflow run: <inner message>'.","triggerScenarios":"pauseWorkflowRun(id, approvalContext) throws a non-'not found' error from the UPDATE/transaction: DB unreachable, SQL syntax/constraint error, transaction abort, or JSON.stringify failure on approvalContext (e.g. circular structure throws TypeError before the UPDATE).","commonSituations":"Passing a non-serializable approvalContext object (circular refs, BigInt) so JSON.stringify throws; transient Postgres connection drops; schema drift where a column referenced by the UPDATE is missing; pool exhaustion.","solutions":["Read the inner err.message: if it is a serialization error, fix the approvalContext passed to pauseWorkflowRun (plain JSON-safe object only)","Check DB connectivity/pool health and retry the pause with backoff for transient errors","Verify the database schema is current (additive migrations applied) for remote_agent_workflow_runs","Confirm the run is still in 'running' state to rule out a concurrent status change causing a locked-row conflict"],"exampleFix":"// before\nawait pauseWorkflowRun(id, { req, callback }); // callback makes it non-JSON-safe\n// after\nawait pauseWorkflowRun(id, JSON.parse(JSON.stringify({ reqId: req.id })));","handlingStrategy":"try-catch","validationCode":"// ensure approvalContext is JSON-serializable before calling\nJSON.stringify(approvalContext); // throws early on circular refs / BigInt\nconst run = await getWorkflowRun(id);\nif (run?.status !== 'running') throw new Error(`run ${id} not pausable (status=${run?.status})`);","typeGuard":"function isPauseFailure(e: unknown): e is Error {\n  return e instanceof Error && e.message.startsWith('Failed to pause workflow run:');\n}","tryCatchPattern":"try {\n  await pauseWorkflowRun(id, ctx);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Workflow run not found')) throw e;\n  // DB-level failure: inspect inner message, retry transient errors\n  if (/ECONNREFUSED|ETIMEDOUT|deadlock|serialization/i.test(e.message)) {\n    await retryWithBackoff(() => pauseWorkflowRun(id, ctx));\n    return;\n  }\n  throw e;\n}","preventionTips":["Pass only plain JSON-safe objects as approvalContext","Apply all schema migrations so remote_agent_workflow_runs matches the binary's expectations","Distinguish the intentional 'not found' error from DB failures exactly as the function does","Monitor pool health; pause failures spike under pool exhaustion"],"tags":["database","workflow","pause","error-wrapping"],"backgroundTag":"database-operation-failed","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}