Save Prompt
The Sidecar Writer Your Training Dataset Has Been Missing
- pipe_opt
- text
What it is
Save Prompt writes a text string to disk as a file - but the format and the placeholders are built for one very specific, very common job: batch captioning for training datasets. If you've ever run a captioner over a folder of images and needed each caption saved next to its image as a .txt sidecar, this is the node that does it inside ComfyUI instead of in a script.
The reason this pattern exists is the dataset convention: a LoRA training set is pairs of files that share a basename - 0001.png and 0001.txt. The trainer walks the folder and reads the caption from the same-name text file. This node exists to produce those pairs, with the source filename baked into the output filename automatically.
How it works
It takes your text, builds a filename from placeholders, and writes the file in one of three formats. txt is the plain caption (and the default - the one trainers want). csv writes name,prompt,negative_prompt rows, useful for prompt-styler style collections. json writes structured output and adds an optional nsfw_level tag (auto-detected from text keywords, or disabled). A JSON-only extra: batch source files keyed by their full filename.
The write modes matter for how you batch:
- new - numbered files (
prefix_0001.txt,prefix_0002.txt), the safe default for separate outputs. - overwrite - clobber the file each run.
- append - add text to an existing file, opening and closing each time.
- append_batch - keeps the file handle open across a batch for speed, auto-closing after 10 seconds idle. This is the one for captioning hundreds of images into one file.
- keep - skip if the file already exists, for resumable runs.
The placeholder engine is the whole point. %source_filename substitutes the source image's basename, %source_folder and %source_base_folder its folder path, plus %counter, %date, %time. The default filename_prefix is just %source_filename, so a caption for D:/images/cat.png lands at cat.txt in the same folder - exactly the sidecar convention. You get the source filename via the optional filename_opt string, or more powerfully via pipe_opt from a Load Image From Folder pipe, which also enables the folder placeholders.
The inputs that matter
- text - the caption/prompt to save.
- use_source_folder - save beside the source image, ignoring
output_path. Default on. - filename_prefix - the placeholder template, default
%source_filename. - extension - txt / csv / json.
- write_mode - new / overwrite / append / append_batch / keep.
- filename_opt / pipe_opt - how the node learns the source filename; pipe_opt wins if both are connected.
Output: text - the saved text, passed through as a list.
When you'd use it
Batch captioning pipelines feeding a training run, saving styled prompts into a CSV for reuse, and any workflow where the caption must land in the same folder as its image with a matching name. If you're building a dataset by hand in ComfyUI, this is the bridge between "I generated the images" and "the trainer has its captions".
Installing it
It's part of ComfyUI_Eclipse:
cd ComfyUI/custom_nodes
git clone https://github.com/r-vage/ComfyUI_Eclipse
pip install -r ComfyUI_Eclipse/requirements.txt
then restart, or install via Manager (search "Eclipse"). The usual lineage note applies: formerly RvTools_v2, legacy nodes removed in v4.0.0, bundled migration tool for old graphs.
Common issues
The big one is placeholders resolving to nothing: if neither filename_opt nor pipe_opt is connected, %source_filename has nothing to substitute and your files land with literal placeholder text in the name. Connect a source, or use a plain prefix. And if append_batch files feel like they close unexpectedly, that's the 10-second idle auto-close working as designed - reopen on the next call. For trainers specifically: make sure your trainer actually wants a .txt sidecar (kohya and ai-toolkit do); the convention is same basename, one caption per file.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | The text/prompt to save to file. | |
| output_path | STRING | Output folder path. Leave empty and enable use_source_folder to save alongside source images. Supports placeholders: %source_folder, %source_base_folder, %counter, %date, %time. | |
| use_source_folder | BOOLEAN | true | When enabled, saves files in the same folder as the source image (from pipe). Ignores output_path. |
| filename_prefix | STRING | %source_filename | Prefix for the filename. Supports placeholders: %source_filename (recommended for batch captioning), %source_folder, %source_base_folder, %counter, %date, %time, etc. |
| filename_delimiter | STRING | _ | Delimiter between filename parts. |
| filename_number_padding | INT | 41β9 | Number of digits for the counter (e.g., 4 = 0001). Only used in 'new' mode. |
| extension | COMBO | txt | File format: txt (plain text), csv (name,prompt,negative_prompt), json. |
| write_mode | COMBO | new | new: numbered files (prefix_0001.txt), overwrite: overwrites existing file, append: adds text to file (opens/closes each time), append_batch: keeps file open for fast batch processing (auto-closes after 10s idle), keep: skip if file exists. |
| csv_positive_name | STRING | β Style | [CSV] Name/label for the style entry (e.g., 'β Line Art / Manga'). |
| csv_negative_prompt | STRING | ugly, deformed, noisy, low poly, blurry, painting | [CSV] Negative prompt text for the style. |
| nsfw_level | COMBO | disabled | [JSON only] NSFW level tagging. 'auto' detects from text keywords. |
| log_prompt | BOOLEAN | false | Log the saved prompt to console. |
| filename_optopt | STRING | Optional: Full filepath to source file (e.g., 'D:/images/cat.png'). Enables %source_filename and %source_folder placeholders without needing a pipe. | |
| pipe_optopt | PIPE | Optional pipe from LoadImageFromFolder. Enables placeholders like %source_filename, %source_folder, %source_base_folder, etc. Overrides filename_opt if both connected. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | β |