{"record":{"id":"e4c27b01547e1474","repo":"coleam00/Archon","slug":"run-run-id-is-paused-waiting-on-sub-run-atten-e4c27b","errorCode":null,"errorMessage":"Run ${run.id} is paused waiting on sub-run ${attention.childRunId} ('workflow:' node '${attention.nodeId}'). Reject the child run instead: /workflow reject ${attention.childRunId} To discard the whole tree, abandon this run.","messagePattern":"Run (.+?) is paused waiting on sub-run (.+?) \\('workflow:' node '(.+?)'\\)\\. Reject the child run instead: /workflow reject (.+?) To discard the whole tree, abandon this run\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/operations/workflow-operations.ts","lineNumber":349,"sourceCode":" */\nexport function assertRejectable(run: WorkflowRun): ApprovalContext | undefined {\n  if (run.status !== 'paused') {\n    throw new Error(\n      `Cannot reject run with status '${run.status}'. Only paused runs can be rejected.`\n    );\n  }\n  const rawApproval = run.metadata.approval;\n  const approval: ApprovalContext | undefined = isApprovalContext(rawApproval)\n    ? rawApproval\n    : undefined;\n  const attention = runAttention(run);\n  switch (attention?.kind) {\n    case 'blocked_on_child':\n      // Same redirect as assertApprovable: the parent's pause is not a rejectable\n      // gate — cancelling the parent here would silently orphan the still-paused\n      // child run. Reject the child (its own gate) or abandon the parent (which\n      // cascade-cancels the subtree) instead.\n      throw new Error(\n        `Run ${run.id} is paused waiting on sub-run ${attention.childRunId} ` +\n          `('workflow:' node '${attention.nodeId}'). Reject the child run instead` +\n          `: /workflow reject ${attention.childRunId}` +\n          ' To discard the whole tree, abandon this run.'\n      );\n    case 'unreadable':\n      // The one deliberate divergence from approve: unreadable gate METADATA is\n      // still rejectable (see this function's doc comment). An unrecognized gate\n      // TYPE is not, and neither is a block pointer with nothing to follow.\n      if (attention.reason === 'malformed_gate') break;\n      throw new Error(unreadableGateMessage(run, attention, approval));\n    case undefined:\n      if (approval && isGateResolved(approval)) {\n        throw new Error(\n          `Workflow run ${run.id} was already ${String(approval.resolved)} and is awaiting resume.`\n        );\n      }\n      break;","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/core/src/operations/workflow-operations.ts#L331-L367","documentation":"When a paused parent run is blocked waiting on a child sub-run ('blocked_on_child'), its pause is not a rejectable approval gate. Rejecting the parent would orphan the still-paused child, so the library redirects the caller to reject the child run (its actual gate) or abandon the parent to cascade-cancel the whole subtree.","triggerScenarios":"Calling workflowRejectCommand on a parent run whose metadata block pointer has attention.kind === 'blocked_on_child' — i.e. the run was paused by a 'workflow:' node delegating to a sub-run that itself sits at a gate.","commonSituations":"An operator lists paused runs, picks the parent of a sub-workflow tree, and tries to reject it; a bot command hits the wrong ID in a parent/child chain; someone wants to unwind a multi-run workflow but addresses the root instead of the leaf gate.","solutions":["Reject the child run instead: run '/workflow reject <attention.childRunId>' on the sub-run named in the message.","If the whole tree should be discarded, abandon the parent run — cascade-cancel will tear down the subtree.","Inspect run metadata's attention/block pointer before rejecting to detect 'blocked_on_child' parents."],"exampleFix":"// before\nawait workflowRejectCommand({ runId: parentId });\n// after\nconst childId = run.metadata?.approval?.attention?.childRunId;\nif (childId) {\n  await workflowRejectCommand({ runId: childId }); // reject the actual gate\n} else {\n  await abandonWorkflow(parentId); // discard whole tree\n}","handlingStrategy":"validation","validationCode":"const attention = run.metadata?.approval?.attention;\nif (attention?.kind === 'blocked_on_child') {\n  // redirect to child\n}","typeGuard":"function isBlockedOnChild(a: unknown): a is { kind: 'blocked_on_child'; childRunId: string; nodeId: string } {\n  return !!a && typeof a === 'object' && (a as any).kind === 'blocked_on_child';\n}","tryCatchPattern":"try { await workflowRejectCommand({ runId: parent.id }); }\ncatch (e) {\n  const m = /waiting on sub-run (\\S+)/.exec((e as Error).message);\n  if (m) await workflowRejectCommand({ runId: m[1] }); // reject child\n  else throw e;\n}","preventionTips":["Inspect the run's attention/block pointer before rejecting parents in sub-workflow trees.","In run lists, label 'blocked_on_child' parents as non-decisional.","Document that reject targets leaf gates, not delegating parents."],"tags":["workflow","subrun","approval-gate","cascade"],"backgroundTag":"wrong-target-run-rejection","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}