{"record":{"id":"8f5d79375393b28d","repo":"coleam00/Archon","slug":"loop-group-node-node-id-failed-at-iteration","errorCode":null,"errorMessage":"Loop-group node '${node.id}' failed at iteration ${String(i)}: ${failedBodyNodes.join('; ')}","messagePattern":"Loop-group node '(.+?)' failed at iteration (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/workflows/src/dag-executor.ts","lineNumber":5061,"sourceCode":"          loopIterations: i,\n        };\n      }\n    }\n\n    // A failed body node fails the group immediately — mirrors the top-level DAG\n    // (any failed node fails the run) and executeLoopNode (an iteration failure stops\n    // the loop). Silently re-running the body would burn AI cost every remaining\n    // iteration and bury the root cause under a generic max-iterations error.\n    const failedBodyNodes = iterBodyNodes.flatMap(n => {\n      const o = scopedNodeOutputs.get(n.id);\n      return o?.state === 'failed' ? [`'${n.id}': ${o.error}`] : [];\n    });\n    if (failedBodyNodes.length > 0) {\n      const errorMsg = `Loop-group node '${node.id}' failed at iteration ${String(i)}: ${failedBodyNodes.join('; ')}`;\n      getLog().warn(\n        { nodeId: node.id, iteration: i, failedCount: failedBodyNodes.length },\n        'loop_group_node.body_node_failed'\n      );\n      await safeSendMessage(platform, conversationId, errorMsg, msgContext);\n      return {\n        state: 'failed',\n        output: lastIterationOutput,\n        error: errorMsg,\n        costUsd: loopTotalCostUsd,\n        ...(loopTotalTokens !== undefined ? { tokens: loopTotalTokens } : {}),\n        loopIterations: i,\n      };\n    }\n\n    // Carry the body's final sequential session into the next iteration (unless\n    // fresh_context forces a reset, handled above by seeding undefined).\n    loopLastSequentialSession = iterCtx.lastSequentialSession;\n\n    // Carry prior-iteration snapshot forward for $LOOP_PREV.* on the next iteration.\n    loopPrevOutputs = new Map(scopedNodeOutputs);\n","sourceCodeStart":5043,"sourceCodeEnd":5079,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/workflows/src/dag-executor.ts#L5043-L5079","documentation":"A loop-group node (packages/workflows/src/dag-executor.ts:5061) iterates over groups and runs body nodes per iteration. If any body node fails during iteration i, the executor stops, sends this message to the conversation, logs 'loop_group_node.body_node_failed', and returns the node in state 'failed' with the last iteration's output.","triggerScenarios":"Inside a loop-group node, one or more body nodes return failed state at iteration i — e.g. a prompt node erroring, a bash node exiting nonzero, or a child failing — with failedBodyNodes listing the failing node names joined by '; '.","commonSituations":"A flaky AI/prompt node failing on one batch item; a bash step in the loop body hitting a bad input for the i-th group; rate limits mid-loop causing a body node to fail; unvalidated group data causing a script to crash.","solutions":["Inspect the listed failed body node names and its error in run events; fix or add retries to that body node","Make the body node tolerant (add retries/timeouts, validate group inputs before the loop)","Gate the loop body on data checks so bad iterations fail fast with a clearer error","Re-run the workflow after fixing; the loop resumes from the start unless the engine supports resumption"],"exampleFix":"// workflow yaml body node\n# before\nbash: run-tests.sh ${item}\n# after\nbash: run-tests.sh ${item} || echo \"tests failed for ${item}, continuing\"  # or add retries: on the node","handlingStrategy":"try-catch","validationCode":"// Validate group data before the loop-group runs:\nconst groups = JSON.parse(groupsOutput);\nif (!Array.isArray(groups) || groups.some(g => g == null)) {\n  throw new Error('loop-group input must be a non-empty array of valid groups');\n}","typeGuard":"function isFailResult(r: { state: string; error?: string }): r is { state: 'failed'; error: string } {\n  return r.state === 'failed' && typeof r.error === 'string';\n}","tryCatchPattern":"try {\n  await runLoopGroup(node);\n} catch (e) {\n  // message pattern: \"Loop-group node '<id>' failed at iteration <i>: <nodes>\"\n  const m = String(e.message ?? e).match(/Loop-group node '([^']+)' failed at iteration (\\d+): (.+)/);\n  if (m) console.error(`fix body node(s): ${m[3]} (iteration ${m[2]})`);\n  else throw e;\n}","preventionTips":["Add retries/timeouts to body nodes that call AI or external services","Validate each group's data before the body runs","Read failedBodyNodes in the message to target the failing node directly","Check run events for the body node's own error before re-running"],"tags":["workflow","loop","node-failed","dag-executor"],"backgroundTag":"workflow-node-iteration-failed","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}