ComfyUI Node

While Loop Start

\"Nothing is happening\" — your While Loop Start condition is False

By wenchengxiang·Created 2 months ago·Updated 9 days ago· 3
While Loop Start
  • initial_value0
  • initial_value1
  • initial_value2
  • initial_value3
  • initial_value4
  • initial_value5
  • initial_value6
  • initial_value7
  • initial_value8
  • initial_value9
  • initial_value10
  • initial_value11
  • initial_value12
  • initial_value13
  • initial_value14
  • initial_value15
  • initial_value16
  • initial_value17
  • initial_value18
  • initial_value19
  • flow
  • value0
  • value1
  • value2
  • value3
  • value4
  • value5
  • value6
  • value7
  • value8
  • value9
  • value10
  • value11
  • value12
  • value13
  • value14
  • value15
  • value16
  • value17
  • value18
  • value19
◄conditiontrue►

What it is

While Loop Start opens a loop that repeats until you say stop - as opposed to the for-loop pair in the same pack, which repeats a fixed count. It's the more general of the two, and the one that makes ComfyUI feel like a programming language: feed a tensor in, have a node that inspects it, wire the verdict back to the loop end, and iterate until the image is good enough, or the mask is empty, or the noise has settled.

You'd reach for it for the jobs where you can't know the iteration count up front: keep upscaling until you hit a pixel budget, keep inpainting until the mask goes black, keep refining until a score crosses a threshold. A fixed for loop can't express any of that.

Worth being honest about the state of the art: loop nodes are the least-documented corner of ComfyUI's plumbing layer. The KB's map of that layer covers wildcards, switches, reroutes and context buses in detail and has nothing on loops at all, and the most-visible community thread on these nodes is someone asking how they work - answered by two people who gave up. The mental model, once it clicks, is small: values come in at the top, values leave at the bottom, and the wire between the two is the loop.

The inputs and outputs

  • condition (BOOLEAN, default True) - the entry gate, on the Start node as a widget. It decides whether the body runs at all. False and the node hands an ExecutionBlocker to every carried value, skipping the whole region between Start and End, so nothing downstream of End gets data. It's an off switch for the loop, and the number-one cause of "I wired this up and the queue finishes in 0.2 seconds with no output".
  • flow (WFLOW_CONTROL out) → While Loop End's flow. The bracket.
  • value0 … value19 (wildcards, twenty slots) - the loop state. On Start, these are the current values of the slots (how they get there is described below). Wire them into your body; anything goes.

Because condition is a required input rather than a hidden one, you can right-click it and convert it to a socket if you want a dynamic pre-test that's re-evaluated every round. But note the asymmetry: the expansion rewrites the carried values when it builds the next round, not the Start's condition - it's While Loop End's condition that drives continuation. Most working loops leave Start at True and put all their logic on the End's condition.

How the loop is wired

The cycle is Start → body → End → (repeats) → Start, and the "wire" that closes it is that whatever you deliver to While Loop End's initial_valueN inputs reappears on While Loop Start's valueN outputs on the next round. That's it. Not a queue, not a buffer - the End takes the values it receives and seeds the next copy of the body with them.

So a working while loop needs exactly three things: a counter or state in a value slot, some node in the body that computes a boolean from it, and that boolean wired into While Loop End's condition. Which is precisely what the pack's for-loop pair does internally, inserting a Loop Step to turn a counter into a "keep going" boolean.

Convention worth copying: the for-loop nodes use value0 for the counter (that's why For Loop Start has an index output and While Loop Start doesn't). If you're building loops by hand, slot 0 is a fine place for it - just be consistent.

Install

ComfyUI Manager, search ComfyUI-Practical-Tools (registry publisher wcx, version 2.0.11), or:

cd ComfyUI/custom_nodes
git clone https://github.com/wenchengxiang/ComfyUI-Practical-Tools

Restart ComfyUI. No dependencies for this node, no model downloads. The pack does declare onnxruntime, nvidia-vfx and openai>=1.0.0 in requirements.txt, but those serve its tagger / RTX-upscale / API nodes, and the pack's loader imports each Python file in isolation - a failure prints a [WCX Nodes Error] line and only takes out that one node, so the loops don't care.

Where people get burned

An infinite loop is your problem. Nothing inside the node caps iterations. If the condition never comes back False - a comparison wired to a value that doesn't change, a total of 0 you expected to be a stop - ComfyUI keeps expanding loop-body copies until something gives. Save your workflow before testing a new loop condition, and start with a small total.

A node in the region that isn't wired to the End isn't in the loop. The body is discovered by walking backwards from the End's inputs. Anything sitting visually "inside" the loop that doesn't feed the End runs once and you'll swear the loop is broken.

Only the wildcard sockets' types are unchecked. * accepts anything, so nothing catches the case where round three hands your sampler a string.

Wildcard state is not state. If you need the previous round's result rather than the current one, that's what Batchloop Accumulate is for; the value slots carry one value per slot, no history.

CategoryPractical-Tools/Logic

Inputs (21)

NameTypeDefaultDescription
conditionBOOLEANtrue—
initial_value0opt*—
initial_value1opt*—
initial_value2opt*—
initial_value3opt*—
initial_value4opt*—
initial_value5opt*—
initial_value6opt*—
initial_value7opt*—
initial_value8opt*—
initial_value9opt*—
initial_value10opt*—
initial_value11opt*—
initial_value12opt*—
initial_value13opt*—
initial_value14opt*—
initial_value15opt*—
initial_value16opt*—
initial_value17opt*—
initial_value18opt*—
initial_value19opt*—

Outputs (21)

NameTypeDescription
flowWFLOW_CONTROL—
value0*—
value1*—
value2*—
value3*—
value4*—
value5*—
value6*—
value7*—
value8*—
value9*—
value10*—
value11*—
value12*—
value13*—
value14*—
value15*—
value16*—
value17*—
value18*—
value19*—