Collect to List
Gather a fan-out back onto one wire
- value
- value
- count
- joined
Here's a ComfyUI behaviour that bites everyone eventually: a node that outputs a list - a list of filenames, a number range, a set of paths from a zip - makes every node downstream of it run once per entry, not once with the whole list. The fan-out is silent and very useful, until you need all those per-entry results back together on one wire for a single save or a video encode. That's the job of Collect to List.
Under WAS Suite/Logic/Loop, it takes a single value input - wire in the last node of the fan-out - and hands you the whole run as one value:
value- everything gathered in one shot. Images, masks, and latents join into a single batch, so five runs of one image become a 5-image batch. Anything else - strings, numbers, models - arrives as a list of five. The socket takes whatever type you wired in.count- how many things are invalue. This one has a subtlety: five runs of a 4-frame batch give 20, because those joined into one 20-frame batch, while five runs of text give 5. Feed it to an iteration count or a batch index.joined- everything written out as one string, separated by yourdelimiter(default", "). Text and numbers appear as-is; an image prints as something likeIMAGE 1x512x512x3. It's a log line for free.
Where the fan-out comes from
WAS Suite's own list sources trigger it: Load Text Files from Zip, Zip Open, Number Range, Number Easing. If any of those feeds a chain, every node downstream runs once per entry - that's the intended iteration. What isn't intended is that the chain usually dead-ends: a video encoder at the end of a per-frame fan-out would try to encode one frame at a time unless you collect first. Wire the last node of the series into Collect to List and the encoder finally sees the whole sequence. It also handles the degenerate case gracefully - a source that only ran once gathers into a collection of one instead of erroring, so the node is safe to leave in place.
The two ways people use it
The batch path: collect images/masks/latents so a video encoder or a single Save Image sees the full sequence instead of each frame. The text path: collect strings and the joined output turns per-iteration results into one caption or one log - "frame 1, frame 2, frame 3" - with \n as the delimiter if you want each entry on its own line. Same node, two completely different jobs, and both are the "put the loop's results back into one tube" pattern.
The mental model that saves debugging time
Think of the fan-out as ComfyUI spawning a little loop, and Collect to List as the loop's return statement. The catch is that the collection point has to be after everything you wanted per-iteration work done on - collect too early and you batch up unfinished pieces; wire the wrong node in and you gather one iteration's output repeated. When the count looks wrong, count backwards to where the list entered the graph: whatever emitted the list is your fan-out source, and the node right before the collect is the last per-entry processing.
Installing
Part of WAS Node Suite v3 (WASasquatch/was-node-suite-comfyui), WASasquatch's MIT pack - going since 2023, over a million downloads, and one of the first suites to give ComfyUI this kind of breadth. Loop/plumbing nodes need nothing extra: no packages, no models. Requires ComfyUI 0.14.0+ (the v3 suite uses ComfyUI's newer node backend).
Install from ComfyUI Manager by searching WAS Node Suite v3, or:
cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/was-node-suite-comfyui
Restart ComfyUI and it's under WAS Suite/Logic/Loop. If it never appears, update ComfyUI first - 0.14.0 or newer is required.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| value | COMFY_MATCHTYPE_V3 | The last node of the fan-out, wired here once. Whatever connects, IMAGE, LATENT, STRING or a model, decides the type of the node, and the value output carries that same type. A source that ran only once gathers into a collection of one rather than failing. | |
| delimiter | STRING | , | Placed between the entries in joined. ', ' builds a comma-separated caption; \n puts each entry on its own line; empty runs them together with nothing between. It changes neither value nor count. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| value | COMFY_MATCHTYPE_V3 | Everything gathered, as one value. Images, masks and latents join into a single batch, so 5 runs of one image give a 5 image batch; anything else arrives as a list of 5. The socket carries the type that was wired into value. |
| count | INT | How many are in value; INT. 5 runs of one image = 5; 5 runs of a 4 frame batch = 20, since those joined into one 20 frame batch; 5 runs of text = 5. Feed it to a batch index or an iteration count. |
| joined | STRING | Every gathered value written out as text, separated by delimiter. Text and numbers appear as they are, an image, mask or latent as its kind and size, 'IMAGE 1x512x512x3'. Save it to log what a run gathered. |