While Loop Close | akatz-loops
The Loop Bottom That Re-Runs Your Graph Until You Say Stop
- flow_control
- initial_value0
- initial_value1
- initial_value2
- initial_value3
- initial_value4
- value0
- value1
- value2
- value3
- value4
If WhileLoopOpen is the top of the loop, this is the part that does the actual work of looping. WhileLoopClose sits at the bottom of the loop body and decides what happens next: if its condition is true, it rebuilds the entire region between itself and the open node as a fresh graph and runs it again; if false, it stops and hands the final values out. One node, both the "loop again" and "we're done" branches, and the engine never sees a cycle.
You wire it like a bookend. Take the FLOW_CONTROL output from WhileLoopOpen into the close node's flow_control input (that link is what tells ComfyUI which open node this loop closes), put your condition logic somewhere in the body feeding the condition BOOLEAN input, and the five value0–value4 outputs are the loop's results. The initial_value0–initial_value4 optional inputs are the previous iteration's values coming back around - wire iteration N's output here and it arrives at the open node as the starting value for iteration N+1.
Why this pattern exists
The community's standard loop complaint - "Comfy always complained about the loop, I couldn't use the output as input for the next iteration" - is precisely the problem this architecture was built to kill. The close node doesn't mutate anything; it expands. Under the hood (in the source), when the condition is true it walks the dependency graph between open and close, builds a GraphBuilder copy of every node in that region with the current iteration's inputs, and returns that as the expanded execution plan. The loop is a for-loop's worth of fresh graph copies, which is why it can feed its own results forward without ever forming a circular link.
The practical shape people actually use: a counter node (or the pack's internal _ForLoopCounter, which is what ForLoopClose wires up automatically) decrements each pass and feeds the close node's condition; the value you're refining - an image, a latent, a prompt - rides through initial_value/value and improves each iteration until the counter hits zero and the condition flips false. That's a for-loop built out of a while-loop, and it's the same machinery this pack's ForLoopOpen/ForLoopClose expose with nicer ergonomics.
Termination is on you
Nothing in ComfyUI proves your loop will end. If the condition never goes false, the graph just keeps expanding - you'll notice it as a run that never finishes (and a workflow file that bloats as copies pile up). Always ensure something inside the body can flip the condition false. The good news: because this is expansion rather than a live cycle, a runaway loop is a "stop the run" problem, not a "crash ComfyUI" one.
Install
Part of Akatz-Loop-Nodes (akatz-ai). Via ComfyUI Manager, search "Akatz-Loop-Nodes"; or:
cd ComfyUI/custom_nodes
git clone https://github.com/akatz-ai/Akatz-Loop-Nodes
Restart ComfyUI. Only dependency in the pack is opencv-python; no models to download. Listings may show the module as custom_nodes.ComfyUI-Execution-Inversion - lineage from BadCafeCode's execution-inversion demo, not a separate install.
Known friction at scale: nested subgraphs plus loops can throw maximum recursion depth exceeded during validation on recent ComfyUI - the confirmed community workaround is installing ComfyUI-GraphConstantFolder (just drop it in custom_nodes, no settings). The recursion error is validation, not your loop; don't rewrite working loop logic chasing it.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| flow_control | FLOW_CONTROL | — | |
| condition | BOOLEAN | — | |
| initial_value0opt | * | — | |
| initial_value1opt | * | — | |
| initial_value2opt | * | — | |
| initial_value3opt | * | — | |
| initial_value4opt | * | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| value0 | * | — |
| value1 | * | — |
| value2 | * | — |
| value3 | * | — |
| value4 | * | — |