Nodes/ControlFlowUtils/⏹️ Loop Close
ComfyUI Node

⏹️ Loop Close

The Other Half of ComfyUI's Only For-Loop

By VykosX·Created 2 years ago·Updated 2 years ago· 147
⏹️ Loop Close
  • LOOP
  • data
  • aux
  • aux2
  • aux3
  • aux4
  • aux5
  • FINISHED?
  • data
  • aux
  • aux2
  • aux3
  • aux4
  • aux5
conditionTrue

You don't use LoopClose alone - it's the closing brace of the only real for-loop ComfyUI has. Its partner LoopOpen starts the loop; LoopClose sits at the end of the block you want repeated, and decides whether to run another iteration or call it done. Most of the interesting machinery actually lives in this node.

What it does

Three jobs, all visible in its inputs and outputs:

1. It terminates the loop. The LOOP input (required) connects to LoopOpen's LOOP output and carries the loop's state - current index, start, step, end, finished flag. LoopClose reads finished from that dict. If it's done, the loop stops and the final data comes out.

2. It holds the per-iteration state. data, aux, aux2–aux5 are optional inputs. Whatever you feed in here at the end of an iteration gets handed back to LoopOpen's matching data/aux outputs as the starting values for the next iteration. That round-trip is the entire mechanism for accumulating anything across iterations - think of it as the loop variable that survives each pass.

3. It runs the next iteration. If the loop isn't finished, LoopClose does the heavy lifting: it asks ComfyUI's Execution Model Inversion machinery (via the GraphBuilder) to clone every node between LoopOpen and LoopClose, wire the current data into the copies, and re-run them. Each iteration is literally a fresh set of node copies. This is the "proof of concept" part the author flags - it's powerful, and occasionally buggy, which is why you want a current ComfyUI and why the README says to report issues.

The outputs are the payoff:

  • FINISHED? - boolean, True once the loop is done. This is your signal to route execution onward (or to loop-chain into another stage).
  • data / aux / aux2–aux5 - the final values after the last iteration. This is how the loop hands its result back to the rest of the workflow.

There's also a condition string input (default "True") so LoopClose can early-exit if a while-style condition stops holding - combined with LoopOpen's own condition you can build "for-range AND while-condition, whichever ends first."

Common traps

The classic mistake is forgetting the state round-trip: you wire a value into LoopOpen's data but never feed the processed result back into LoopClose's data. The loop still runs, but every iteration sees the same starting value, so nothing accumulates and you get N identical results. If your loop isn't progressing, trace the data/aux loop first.

Second, memory. Every iteration's node copies and outputs stay cached, so a long loop can balloon RAM. That's expected behavior for this execution model - drop a GarbageCollector node inside the loop body and batch long runs rather than expecting a 1000-iteration loop to be free. There's real-world confirmation of this: a popular 1000-image img2img animation built on these loop nodes had to be split into batches because ComfyUI kept every iteration in memory.

Third, version. If LoopClose refuses to run and complains about being unable to create the loop system, your ComfyUI is too old - the Execution Model Inversion backend is a relatively recent core feature.

Install

LoopClose ships in VykosX/ControlFlowUtils:

# ComfyUI Manager → Install Custom Nodes → search "ControlFlowUtils"
# or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/VykosX/ControlFlowUtils

Restart, find it under 🐺 VykosX-ControlFlowUtils, and start from one of the repo's sample loop workflows - the screenshots and demos teach the data round-trip faster than reading about it.

Category🐺 VykosX-ControlFlowUtils

Inputs (8)

NameTypeDefaultDescription
LOOP*Connect to the LOOP output of a [Loop Open] node to establish a Loop
conditionSTRINGTrueThe loop will be executed only if the specified condition evaluates to True
dataopt*Any data you wish to iterate on in the loop
auxopt*Any auxilliary data you wish to iterate on in the loop
aux2opt*Any auxilliary data you wish to iterate on in the loop
aux3opt*Any auxilliary data you wish to iterate on in the loop
aux4opt*Any auxilliary data you wish to iterate on in the loop
aux5opt*Any auxilliary data you wish to iterate on in the loop

Outputs (7)

NameTypeDescription
FINISHED?BOOLEANThis output will return True when the Loop is done executing
data*Final values for any Data that has been processed by the Loop
aux*Final values for any Data that has been processed by the Loop
aux2*Final values for any Data that has been processed by the Loop
aux3*Final values for any Data that has been processed by the Loop
aux4*Final values for any Data that has been processed by the Loop
aux5*Final values for any Data that has been processed by the Loop