Text Add Rows (CRT)
Append to .txt without ever overwriting
- file_path
- file_content
Some ComfyUI nodes earn their keep by being the place a workflow's finished data lands, and Text Add Rows (CRT) is exactly that: every time the graph runs, it takes whatever string comes in on text and appends it as one line to a plain .txt file on disk. It's the sink of the pack's Q/A pipeline - the final node that catches completed JSON pairs from Merge Q/A (CRT) and builds up your training file - but it's general enough to log prompts, captions, or any per-run output you want to keep.
The design decision that matters is that it never overwrites. If the filename you asked for already exists, it walks up to _1, _2, and so on until it finds a free name. Combined with appending (rather than truncating), that means no run of your workflow can clobber data from a previous one. The node even remembers which file it's attached to between runs, so repeated executions append to the same file rather than spawning a fresh copy each time.
Here's the mechanism worth knowing, because it's why it behaves the way it does:
- Empty
pathmeans ComfyUI's own output directory; otherwise it uses the folder you give it (and creates it if missing). So by default your file lands inComfyUI/output. - Empty
filenamebecomesText_Add_Rows.txt. No extension? It appends.txtfor you. - It's an
OUTPUT_NODE, and itsIS_CHANGEDalways returns a fresh value - which is ComfyUI's way of forcing the node to re-run on every queue. That's deliberate: a log node that only ran when its inputs changed would miss half your runs. - Incoming newlines are collapsed to spaces, so each execution genuinely adds exactly one row, even if the text itself is multi-line.
The two outputs are the same data twice, for different jobs: file_path is the absolute path to the file it appended to, and file_content is the entire current file as one string. If you want to watch the log grow inside ComfyUI, wire file_content into a text preview; if you want the path, wire file_path wherever a save location is needed. Both work because a .txt file is just a string with extra steps.
Now the gotchas, because this node rewards knowing them:
- It accumulates forever. Re-running the same workflow appends another copy of every row. That's the feature when you're building a dataset one generated pair at a time, and the trap when you re-run a workflow to test something and silently triple your training file. Check your file before you feed it to anything.
- The numeric suffix is a startup decision. If
Text_Add_Rows.txtalready exists when the node first resolves its path, you getText_Add_Rows_1.txtand you'll keep appending there. Rename or delete the old file if you want a clean log. - It's an output node, so it forces itself to run at the end of the graph's execution order. That's what you want for a logger; it also means a broken workflow upstream can prevent the row from being written.
Installation is the standard pack clone:
cd ComfyUI/custom_nodes
git clone https://github.com/PGCRT/CRT-Nodes
then restart. Or search "CRT-Nodes" in ComfyUI Manager. This node uses nothing but the Python standard library and ComfyUI's folder_paths, so ignore the pack's heavyweight requirements.txt (transformers, whisper, opencv…) if you're only after the text nodes - it's entirely for the audio and model nodes elsewhere in the pack.
Plain-text logging isn't glamorous, and that's the point. When you're generating data across hundreds of runs, you want a node you never have to think about, one that writes a row per run and cannot lose what you already had. That's this one.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | The text to append as one row. | |
| path | STRING | Folder path where the .txt file is saved. If empty, uses ComfyUI's output directory. | |
| filename | STRING | Filename for the .txt file. If empty, uses Text_Add_Rows.txt. If a file with that name already exists, a numeric suffix is appended. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| file_path | STRING | Absolute path to the file that was appended to. |
| file_content | STRING | Full current content of the file as a string. |