NestWhile
The while loop with a leash
- function
- x
- predicate
- *
NestWhile is Nest with a brain: instead of running a fixed number of times, it keeps applying the function until a condition stops being true. It's a real while loop in ComfyUI - and with that power comes the pack's most advertised footgun. The README's troubleshooting sheet exists partly because of this node.
The inputs
function- aCLOSUREthat transforms the current value.x- the starting value.predicate- aCLOSUREthat takes the current value and returns a BOOLEAN (True= keep going).max_depth- the safety cap. Default 10, range 1–100. This is your leash.- output - the final value.
The loop's rhythm: check the predicate on the current value; if it returns False, stop; otherwise apply the function and repeat. If the predicate never turns False, max_depth saves you. Iterative refinement is the classic job - "keep denoising until the image stops changing," "keep reducing until error is below threshold."
Why max_depth is non-negotiable
This is the infinite-loop node, and the pack knows it. There's no termination condition built in beyond your predicate, and a predicate that never flips means an endless expansion of graph nodes. The coroutine machinery has COMFYUI_FUNCTIONAL_COROUTINE_LIMIT (default 100) as a backstop and throws a RecursionError when you blow past it - but don't rely on the backstop. Keep max_depth sane. If you don't actually need a conditional stop, Nest is simpler and can't hang.
How it works
Same coroutine machinery as the rest of the high-order nodes: each iteration yields the predicate call, checks the result, then yields the function call, threading the value through. Every iteration re-expands the function body into real graph nodes with fresh IDs, so nothing caches and each pass costs full runtime. The loop itself is bounded by max_depth and the coroutine limit; the body is bounded by nothing, so a function that itself recurses can still spin.
Where people get burned
- Predicate never returns False → the loop hits max_depth or the coroutine limit. Check the predicate's logic, not the loop.
- Predicate must return a real BOOLEAN - if your predicate hands back a string or a number, comparisons downstream get weird. Keep it boolean.
- Silent full-depth runs - a loop that always runs to max_depth looks identical to a correct one until you count. If behavior "just ends after N," the predicate was never consulted.
Installing it
Ships in Duanyll/comfyui_functional. ComfyUI Manager: search "Duanyll/comfyui_functional", or:
cd ComfyUI/custom_nodes
git clone https://github.com/Duanyll/comfyui_functional
# restart ComfyUI
No models, no pip deps; grab Basic Data Handling for LIST support. Use it when the stop condition genuinely depends on the value - otherwise Nest gives you the same power with fewer ways to hang.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| function | CLOSURE | — | |
| x | * | — | |
| predicate | CLOSURE | — | |
| max_depth | INT | 101–100 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| * | * | — |