Text Loader
Point It at a Folder and Each Run Reads a Different Prompt
- text
- file_path
What it's for
There are two ways to get prompt variety without writing more prompts. One is the {brown|blonde|black} hair bracket trick inside a single text box, which is old A1111 wildcard syntax and still the fastest option. The other is keeping your prompts as files - a folder of character descriptions, one prompt per .txt, a pile of caption snippets - and having the graph pull one per run.
Text Loader is the second kind. You give it a folder, it gives you back the contents of one file as a STRING, plus the path it read. That's it, and that's the point: batch-queue twenty runs and you get twenty different prompts out of a single workflow, with your prompt library living in a text editor instead of a three-line textbox on the canvas.
It's also the sane way to keep prompts out of the graph when they're long. A 400-word structured video prompt pasted into a CLIP Text Encode widget is miserable to edit and easy to lose; as prompts/character_a.txt it's just a file.
How it works
The pack has one shared file-picker used by all its loader nodes, and the behaviour is worth knowing exactly. It validates that folder_path is a real directory (otherwise: Invalid folder path), then globs prefix*.<ext> once per extension, sorts the results, optionally reverses, then either picks randomly (seeded) or takes your index - and finally reads the file as UTF-8 text. Two outputs: text and file_path.
Two consequences fall out of that. It looks one level deep only - no recursion, so a nested prompt library won't be found. And file_path exists mostly for debugging: feed a Show Text node and you can see which file produced the image you're looking at.
The inputs that matter
- folder_path (required) - an absolute path on the machine running ComfyUI. The real reference is the filesystem, not your browser, so
~isn't expanded and a remote ComfyUI needs the folder on the remote box.ComfyUI/input/is a convenient place to keep them if you don't want to think about it. - file_idx - which file in the sorted order to read. In the source this widget carries the
control_after_generatedropdown, which is the whole recommended workflow: set it to increment, queue N runs, and you walk through the folder one prompt at a time. Do remember that dropdown defaults to firing after a run, so the number showing is the next one to be used; switching ComfyUI's "widget control mode" to Before once makes the box honest. - random_idx + seed - the other strategy: ignore the index and pick a random file. The seed makes it reproducible, so the same seed hands you the same file. Note that randomising the pick across queue runs means randomising the seed, which this node won't do for you.
- sort_by (
name,date,shuffle) and reverse - the ordering. If you want a deliberate sequence, usenameand number your files001_,002_. - extension (
all,txt,md,json), prefix - filters.allmeans the three text extensions together.
Install
ComfyUI Manager, search Sagado Nodes, or:
cd ComfyUI/custom_nodes
git clone https://github.com/5agado/ComfyUI-Sagado-Nodes
cd ComfyUI-Sagado-Nodes
pip install -r requirements.txt
Restart ComfyUI. There's nothing to download - this node touches no models - and the README is a stub, so the node itself is your documentation.
Where people get burned
"date" isn't the date you think. It sorts on the file's st_ctime - inode change time on Linux, which for files you just copied or rsynced is when they landed, not when they were created or last edited. A folder that looks chronological in your file manager can come out in a strange order here. Number your files and sort by name instead.
Empty prompt, no error. If a file exists but can't be decoded, the failure is printed to the console and the node returns an empty string rather than crashing. So an inexplicably blank prompt usually means the encoding isn't UTF-8. Conversely, an index past the end of the folder, or a folder with nothing matching, does raise loudly - those you'll see.
Extensions are case-sensitive on Linux. *.txt won't match PROMPT.TXT. Same for prefix, which is pasted into a glob pattern.
.json is read as raw text, not parsed. You get the literal JSON string in your prompt. If you were hoping to pluck a field out of a config file, this node isn't that; it's a text reader with a file chooser attached.
Wire text into a CLIP Text Encode, or into one of the pack's other text utilities - the Wildcard Processor, or Call LLM API if you want to pick a file and then have a model expand it. Pick-a-random-file → enhance → generate is a genuinely nice two-step loop.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| folder_path | STRING | — | |
| file_idxopt | INT | 0 | — |
| random_idxopt | BOOLEAN | false | — |
| sort_byopt | STRING | date | — |
| reverseopt | BOOLEAN | false | — |
| seedopt | INT | 42 | — |
| extensionopt | COMBO | all | 4 options: all, txt, md, json |
| prefixopt | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |
| file_path | STRING | — |