Foreach Prompt
Batch a whole list of prompts through one workflow
- prompt
The name oversells it a little. Foreach Prompt doesn't contain a loop - it's a splitter. You paste a big block of prompts separated by a delimiter, and it hands ComfyUI a list, which is the part that actually does the iterating. If you've ever run 20 variations of a prompt by editing the text box and hitting Queue 20 times, this is the node that makes it one click.
What it actually does
Under the hood it's one line: prompts_string.split(delimiter). It takes one big string, cuts it wherever your delimiter appears, and returns the pieces as a list output. The magic - and the reason this works at all - is that the node declares its output as a list (OUTPUT_IS_LIST = True), and ComfyUI's execution engine expands downstream nodes once per item. Wire prompt into the text input of a CLIP Text Encode and the whole chain after it - sampler, VAE decode, Save Image - runs once per prompt, and you get one saved image per prompt.
So the mental model is: you don't write a loop, you emit a list, and the engine fans the graph out. Same trick the bigger iteration packs use, minus all their machinery. The author's example workflow shows the intended wiring: a Text Multiline node feeding prompts_string, then Foreach Prompt → positive CLIP Text Encode → KSampler → Save Image. That's the whole thing.
The inputs and outputs that matter
There are exactly two inputs, and you'll touch both:
- prompts_string (required, STRING): your block of prompts, one after another. Type it in the box or convert the widget to an input and wire in a Text Multiline node like the example does.
- delimiter (optional, STRING, default
---): the string that separates prompts. Keep the default unless you have a reason not to.
The single output is prompt (STRING, as a list). It feeds any node that takes a string - usually the positive text encoder, but it'll also happily drive an SD3/Flux text encoder or whatever else wants a STRING. There's nothing else to configure, which is both the appeal and the ceiling.
Install
Through ComfyUI Manager, search "comfy-loop-utilities" and hit install. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/O-oshir/comfy-loop-utilities
Then restart ComfyUI. The README's pip install -r requirements.txt step is a formality here - the requirements file is empty and the project declares no dependencies. There are no models to download. One real wrinkle: the pack's __init__.py does import cm_global, a module ComfyUI Manager drops into custom_nodes/. If you installed without Manager and the pack silently fails to load, that import is why - install Manager first (you almost certainly already have it).
Where people get burned
- Whitespace. The split is raw - no trimming. Put the delimiter on its own line and every prompt except the first keeps a trailing newline, every one except the last keeps a leading newline. The author's own example does exactly this (you can see the stray
\nin the split output). CLIP doesn't care about leading/trailing whitespace, so in practice it's harmless - until it isn't, like if you pipe the result into an LLM node or a template that's picky. - Pick a delimiter that can't appear inside a prompt. If "---" shows up in a real prompt, you'll silently get an extra split. Something like
###or:::is safer for long prompt blocks. - Empty strings are real. A trailing delimiter, or two delimiters in a row, produce an empty item - and an empty item means a generation run on an empty prompt. You'll see it as one wasted, garbage image at the end of the batch.
- It won't auto-rerun. Unlike nodes that return
NaNfromIS_CHANGEDto force execution, this one is a pure function of its inputs. Edit the prompt block, run again, and ComfyUI's cache correctly picks up the change - but if you expected "loop forever," that's not this. For one-shot prompt batching it's exactly right.
Should you reach for it?
If your job is "generate one image per prompt from a pasted list," Foreach Prompt is the smallest thing that does it - zero deps, two inputs, done. If you want fancier looping - iterate over seeds and prompts, or dynamic {a|b|c} wildcard expansion - Impact Pack's wildcard syntax and the rgthree suite cover that ground with more control. But for the plain case, the simple splitter wins, and this one is about as simple as they come.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| prompts_string | STRING | — | |
| delimiteropt | STRING | --- | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| prompt | STRING | — |