coleam00/Archon · error

Loop-group node '${node.id}' exceeded max iterations (${Stri

Error message

Loop-group node '${node.id}' exceeded max iterations (${String(group.max_iterations)}) ${describeUnmetCompletion(group)}

What it means

A loop-group node (packages/workflows/src/dag-executor.ts:5404) ran up to group.max_iterations without its until/completion condition being satisfied. The executor logs 'loop_group_node.max_iterations_reached', notifies the conversation, and returns the node failed with the last iteration's output; describeUnmetCompletion appends why the completion signal was unmet.

Source

Thrown at packages/workflows/src/dag-executor.ts:5404

        // finalizeLoopFromSignal call above). Only the plain `loop` gate carries it.
      });
      return {
        state: 'completed',
        output: lastIterationOutput,
        costUsd: loopTotalCostUsd,
        ...(loopTotalTokens !== undefined ? { tokens: loopTotalTokens } : {}),
        loopIterations: i,
      };
    }
  }

  // Max iterations exceeded.
  const errorMsg = `Loop-group node '${node.id}' exceeded max iterations (${String(group.max_iterations)}) ${describeUnmetCompletion(group)}`;
  getLog().warn(
    { nodeId: node.id, maxIterations: group.max_iterations, signal: group.until },
    'loop_group_node.max_iterations_reached'
  );
  await safeSendMessage(platform, conversationId, errorMsg, msgContext);
  return {
    state: 'failed',
    output: lastIterationOutput,
    error: errorMsg,
    costUsd: loopTotalCostUsd,
    ...(loopTotalTokens !== undefined ? { tokens: loopTotalTokens } : {}),
    loopIterations: group.max_iterations,
  };
}

/**
 * Clone a body node with `$LOOP_PREV.<id>.output[.field]` refs and `$LOOP_USER_INPUT`
 * pre-substituted into every text field a body executor reads prompts from. Used by
 * {@link executeLoopGroupNode} so the sealed body sub-DAG's executors stay unaware of the
 * enclosing loop iteration (the body's own executors call substituteWorkflowVariables, but
 * that uses the run's user_message — not the loop's per-iteration user input — so
 * $LOOP_USER_INPUT must be resolved here, at the loop-group level).
 *

View on GitHub (pinned to 0773b97458)

Solutions

  1. Read describeUnmetCompletion in the message to see why the condition was never met
  2. Raise max_iterations on the loop-group node if the work legitimately needs more passes
  3. Make sure body nodes emit the exact structured field the until condition checks (use structured output)
  4. Add per-iteration failure handling so a stuck iteration fails fast instead of burning all iterations

Example fix

# workflow yaml
# before
max_iterations: 3
until: "${loop.all_passed}"
# after
max_iterations: 10
until: "${loop.all_passed}"  # and ensure body node outputs include all_passed
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check that the completion signal's field is actually produced by the body:
const out = await runBodyNodeOnce(group);
if (!(completionField in out)) {
  throw new Error(`body output missing completion field '${completionField}' — until will never be satisfied`);
}

Type guard

function hasCompletionField(o: unknown, field: string): o is Record<string, unknown> {
  return typeof o === 'object' && o !== null && field in o;
}

Try / catch

try {
  const r = await runLoopGroup(group);
  if (r.state === 'failed' && r.error?.includes('exceeded max iterations')) {
    console.error(r.error); // includes describeUnmetCompletion — read why the signal was unmet
  }
} catch (e) { /* escalate: loops should not be retried blindly */ }

Prevention

When it happens

Trigger: A loop-group whose until condition (e.g. all-done signal, convergence check) never becomes true within max_iterations — completion detection depends on structured output the model/script never emits, or the task genuinely needs more iterations than allowed.

Common situations: Prompt nodes never emitting the expected completion field so the check never passes; max_iterations set too low for the batch size; a condition written against the wrong output field; AI responses drifting from the expected schema.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/b45042e9905c8398. Report an issue: GitHub.