Nodes/comfyui-bulk-prompt/πŸ“‹ Bulk Prompt Loader (CSV / Sheets)
ComfyUI Node

πŸ“‹ Bulk Prompt Loader (CSV / Sheets)

Batch-run a whole CSV of prompts by pressing Queue once

By sifatradsΒ·Created 3 months agoΒ·Updated 3 months agoΒ· 0
πŸ“‹ Bulk Prompt Loader (CSV / Sheets)
    • positive
    • negative
    • filename_tag
    • current_row
    • total_rows
    • is_last_row
    β—„sourceβ–Ύβ–Ί
    β—„csv_fileβ–Ύβ–Ί
    β—„sheets_urlhttps://docs.google.com/spreadsheets/d/.../pub?output=csvβ–Ί
    β—„positive_columnpositiveβ–Ί
    β—„negative_columnnegativeβ–Ί
    β—„tag_columnfilename_tagβ–Ί
    β—„auto_loopenabledβ–Ί
    β—„loop_forevernoβ–Ί
    β—„reset_on_startyesβ–Ί
    β—„manual_index0β–Ί
    β—„pasted_dataβ–Ί

    You have two hundred prompts in a spreadsheet, and you are not going to paste them into a CLIP Text Encode one at a time. The Bulk Prompt Loader is the node that makes "queue once, walk away" real: each run of your workflow gets one row from your list, and when that run finishes the node queues the next one itself. Press Queue, go make coffee, come back to a folder full of images. It's the centerpiece of the sifatrads/comfyui-bulk-prompt pack, and everything else in the pack exists to feed it or reset it.

    What it actually does

    It reads rows from one of three sources - a CSV file on disk, a published Google Sheets URL, or text you paste into the node - and spits out one row's worth of strings per execution. Wire positive into your CLIP Text Encode (positive), negative into the negative one, and every generation uses that row. The load happens fresh each run, so you can edit the CSV while ComfyUI is still open and the next row sees the change.

    The mechanism is worth knowing before you trust it: the auto-loop is driven from the browser, not the backend. The node's JS calls a /bulkprompt/loader/continue endpoint then re-queues the prompt after each run finishes. That's why the README's warning matters - keep the ComfyUI tab open and awake, or the batch silently stops. The row position lives in manual_index, which is the single source of truth: the front-end writes the current row back into it after every step, and it's persisted in a state.json inside the node folder, so an interrupted batch resumes where it left off. The node also returns float("nan") from IS_CHANGED (the always-rerun trick, if you've seen the phrase) so ComfyUI's cache never skips it.

    The inputs that matter

    There are a lot of widgets, but a beginner sets four:

    • source - CSV File, Google Sheets URL, or Paste Text. Everything below depends on this.
    • csv_file - a dropdown of the .csv files sitting in ComfyUI/custom_nodes/ComfyUI-BulkPrompt/csv_files/. Drop your file there, refresh, pick it.
    • auto_loop - enabled (default) means the node re-queues itself until every row is done. This is the entire point of the node; leave it on.
    • reset_on_start - yes starts every fresh Queue press at row 0. Set it to no and the batch continues from wherever manual_index left off.

    The column names are flexible: positive_column, negative_column, and tag_column default to positive / negative / filename_tag, but set them to match whatever your header row says. loop_forever (yes/no) wraps back to row 0 after the last row instead of stopping. manual_index is the live counter - you can scrub it by hand to jump to a specific row, which is handy for testing one prompt before committing to the whole batch. pasted_data is only used when source is Paste Text, and it auto-detects: one prompt per line, a comma-separated line, or full CSV with headers.

    Outputs and what to do with them

    • positive / negative - the prompt strings. Feed them to your CLIP Text Encode nodes.
    • filename_tag - a short per-row label. Concatenate it into your Image Saver's filename so each image is named after its prompt row. Do this from day one; retroactively matching 200 images to prompts is misery.
    • current_row, total_rows, is_last_row - integers and a boolean you can use for downstream logic, like a node that only runs on the final image.

    Installing it

    This is the nice part: the core loader has zero Python dependencies - it's standard-library csv, urllib, and json only, so there's nothing to pip install. Via ComfyUI Manager, search for "bulk prompt". Or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/sifatrads/comfyui-bulk-prompt.git
    

    Then restart ComfyUI. The nodes land under BulkPrompt in the menu.

    Where people get burned

    • The batch stops mid-way with no error. The auto-loop is browser-driven, so any tab refresh, sleep, or close kills it. Keep the tab open. The counter is saved, so just re-queue to continue.
    • "No data rows found" - your CSV is empty, or you pointed the file dropdown at the placeholder (no csv files found) entry. Check the csv_files folder.
    • Row counter weirdness after editing pasted text - changing the paste resets the run to row 0 by design (it keys state on a hash of the text).
    • One stale README line says to set reset_counter β†’ yes on the loader. That input doesn't exist in the current node - the loader-side control is reset_on_start, and there's a dedicated Bulk Prompt Reset Counter node for clearing everything.

    Honest caveat: this pack is brand new (basically zero install base as of this writing), so expect rough edges. The pattern is proven - it's the same niche as the older CSV-to-Prompt node, just with a live counter and a browser-driven loop instead of the seed/batch-count trick.

    CategoryBulkPrompt

    Inputs (11)

    NameTypeDefaultDescription
    sourceCOMBO3 options: CSV File, Google Sheets URL, Paste Text
    csv_fileCOMBO1 options: example_prompts.csv
    sheets_urlSTRINGhttps://docs.google.com/spreadsheets/d/.../pub?output=csvβ€”
    positive_columnSTRINGpositiveβ€”
    negative_columnSTRINGnegativeβ€”
    tag_columnSTRINGfilename_tagβ€”
    auto_loopCOMBOenabledAuto-queue the next prompt until all rows are done
    loop_foreverCOMBOnoAfter the last row, loop back to row 0
    reset_on_startCOMBOyesyes = each Queue press starts the batch at row 0. no = start at manual_index (which keeps counting up as the loop runs).
    manual_indexINT00–99999Live row counter (0-based: 0 = first row). It auto-advances as the loop runs; edit it to jump. reset_on_start=yes starts each Queue at 0; reset_on_start=no starts at this value.
    pasted_dataSTRINGUsed when source = Paste Text. One prompt per line, a comma-separated list on one line, or full CSV (header row + rows).

    Outputs (6)

    NameTypeDescription
    positiveSTRINGβ€”
    negativeSTRINGβ€”
    filename_tagSTRINGβ€”
    current_rowINTβ€”
    total_rowsINTβ€”
    is_last_rowBOOLEANβ€”