ComfyUI Node

Text Loader

Point It at a Folder and Each Run Reads a Different Prompt

By 5agado·Created about a year ago·Updated about 13 hours ago· 3
Text Loader
    • text
    • file_path
    ◄folder_path►
    ◄file_idx0►
    ◄random_idxfalse►
    ◄sort_bydate►
    ◄reversefalse►
    ◄seed42►
    ◄extensionall►
    ◄prefix►

    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_generate dropdown, 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, use name and number your files 001_, 002_.
    • extension (all, txt, md, json), prefix - filters. all means 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.

    CategorySagado-Nodes

    Inputs (8)

    NameTypeDefaultDescription
    folder_pathSTRING—
    file_idxoptINT0—
    random_idxoptBOOLEANfalse—
    sort_byoptSTRINGdate—
    reverseoptBOOLEANfalse—
    seedoptINT42—
    extensionoptCOMBOall4 options: all, txt, md, json
    prefixoptSTRING—

    Outputs (2)

    NameTypeDescription
    textSTRING—
    file_pathSTRING—