{"record":{"id":"68a7791be2e54191","repo":"coleam00/Archon","slug":"failed-to-find-resumable-run-by-parent-conversatio","errorCode":null,"errorMessage":"Failed to find resumable run by parent conversation: ${err.message}","messagePattern":"Failed to find resumable run by parent conversation: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/db/workflows.ts","lineNumber":879,"sourceCode":"    const result = await pool.query<WorkflowRun>(\n      `SELECT * FROM remote_agent_workflow_runs\n       WHERE workflow_name = $1\n         AND parent_conversation_id = $2\n         AND codebase_id = $3\n         AND status IN ('failed', 'paused')\n       ORDER BY CASE WHEN status = 'paused' THEN 0 ELSE 1 END, started_at DESC\n       LIMIT 1`,\n      [workflowName, parentConversationId, codebaseId]\n    );\n    const row = result.rows[0];\n    return row ? normalizeWorkflowRun(row) : null;\n  } catch (error) {\n    const err = error as Error;\n    getLog().error(\n      { err, workflowName, parentConversationId, codebaseId },\n      'db.workflow_run_find_resumable_by_parent_failed'\n    );\n    throw new Error(`Failed to find resumable run by parent conversation: ${err.message}`);\n  }\n}\n\nexport async function resumeWorkflowRun(\n  id: string,\n  cursor?: WorkflowResumeCursor\n): Promise<WorkflowRun> {\n  const dialect = getDialect();\n\n  // Split into UPDATE + SELECT to support both PostgreSQL and SQLite\n  // (SQLite does not support RETURNING on UPDATE statements)\n  // Each phase has its own try/catch to avoid string-sniffing own errors in a shared catch.\n  let updateResult: { rowCount: number };\n  try {\n    // Refresh started_at to NOW so the resumed row competes fairly with\n    // currently-active rows in getActiveWorkflowRunByPath's older-wins\n    // tiebreaker. Without this, a resumed row carries its original\n    // (potentially hours-old) started_at and would sort ahead of any","sourceCodeStart":861,"sourceCodeEnd":897,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/core/src/db/workflows.ts#L861-L897","documentation":"findResumableRunByParentConversation finds a failed/paused run for a workflow scoped to a parent conversation and codebase, used to detect approved runs needing foreground resume. DB errors are logged (db.workflow_run_find_resumable_by_parent_failed) and rethrown wrapped in this message. Absence of a run is a null return, not an error.","triggerScenarios":"Calling findResumableRunByParentConversation({ workflowName, parentConversationId, codebaseId }) while the DB is down, the schema lacks the parent_conversation_id/codebase_id columns, or the SELECT fails on permissions/timeout.","commonSituations":"Database opened by an older binary before those columns were added; connection reset during message handling; wrong database selected in a staging environment.","solutions":["Inspect the wrapped err.message for schema or connectivity clues.","Apply schema upgrades so parent_conversation_id and codebase_id exist on workflow_runs.","Restore connectivity and retry; the lookup is read-only and safe to repeat."],"exampleFix":"// before\nconst run = await findResumableRunByParentConversation({ workflowName, parentConversationId, codebaseId });\n// after\ntry {\n  const run = await findResumableRunByParentConversation({ workflowName, parentConversationId, codebaseId });\n  if (run) void resumeForeground(run);\n} catch (err) {\n  getLog().error({ err }, 'foreground_resume_detection_failed');\n}","handlingStrategy":"try-catch","validationCode":"// Verify scoped columns exist before relying on foreground-resume detection\nconst check = await pool.query(\n  `SELECT column_name FROM information_schema.columns WHERE table_name='workflow_runs' AND column_name IN ('parent_conversation_id','codebase_id')`\n);\nif (check.rowCount < 2) throw new Error('schema upgrade required for parent-conversation resume');","typeGuard":"function isParentResumeLookupError(err: unknown): err is Error {\n  return err instanceof Error && err.message.startsWith('Failed to find resumable run by parent conversation:');\n}","tryCatchPattern":"try {\n  const run = await findResumableRunByParentConversation({ workflowName, parentConversationId, codebaseId });\n} catch (err) {\n  // A failed lookup must not silently skip resume — surface it to the operator.\n  getLog().error({ err }, 'foreground_resume_check_failed');\n  throw err;\n}","preventionTips":["Apply additive schema upgrades before deploying binaries that read new columns.","Retry transient connection errors — the lookup is read-only.","Log-and-surface instead of swallowing: skipping resume detection can orphan approved runs.","Monitor db.workflow_run_find_resumable_by_parent_failed events."],"tags":["database","workflow-resume"],"backgroundTag":"database-query-failed","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}