Runtime Text Input
Edit a prompt while the queue runs — Runtime Text Input
- text
Here's the frustration Runtime Text Input solves: you queue a batch, and every job is locked to the prompts as they were when you hit Run. This node is the escape hatch. It's a plain multiline text field that outputs a STRING - but with a twist: every queued job re-reads the text at execution time, so you can edit the prompt between jobs and have the next image pick up your change. No re-queueing, no touching the sampler.
It comes from ruminar's String Join Tools pack, and it's the input-side companion to the pack's Runtime Toggle String Join nodes. If you can change the text live and change the toggles live, a long queue stops being a commitment and starts being a session.
How it works
The node syncs its text to a state store on the ComfyUI server, keyed by state_key. When it executes, it reads the latest server-accepted text rather than the value captured at queue time. The queue-time value is only a fallback for when no live state exists. Two implementation details shape how it feels:
- It never caches. The node's
IS_CHANGEDreturnsNaN- the standard ComfyUI idiom for "always re-run this" - so every queued job executes it and pulls the freshest text. The flip side, familiar from the plumbing layer, is that a node stuck onNaNalso defeats caching for everything downstream of it. That's the price of liveness, and here it's exactly what you asked for. - The status bar tells you what's happening. You'll see
EDITING(local text changed, waiting to send),SYNCING(update in flight),LIVE(server acknowledged the text), orSYNC ERROR(update rejected; the visible text is kept for retry).
The sync is deliberately careful: it serializes updates so an old response can't overwrite newer edits, it waits for Japanese IME composition to finish before sending, and it preserves your text exactly - empty strings, leading/trailing whitespace, line breaks, Unicode, backslashes, all of it. Character count is measured in Unicode code points. There's a 512 KiB acceptance limit; beyond that the update is rejected.
What you set
text- the multiline field you edit. It's a widget, not a wire.state_key- auto-generated per node; leave it alone unless you want copies to share live state.- Output:
text, a singleSTRING.
Two small keyboard niceties: while the field is focused, Ctrl+S / Cmd+S saves the ComfyUI workflow instead of the browser's Save Page dialog (add Shift for Save As), and the save also flushes any pending live-text sync.
Installing it
ComfyUI Manager: search "String Join Tools" or "ComfyUI-StringJoinTools". Or:
cd ComfyUI/custom_nodes
git clone https://github.com/ruminar/ComfyUI-StringJoinTools
Restart and refresh. No Python packages, no models. Under String Join Tools.
The gotchas, honestly
Live state lives in server memory and is wiped on a ComfyUI restart - after that, saved values take over until you edit. Deleting the node doesn't immediately delete its state, so already-queued jobs can still resolve it (and workflow copies sharing a state_key can overwrite each other). Also keep the semantics straight: a live empty string is a real state - it does not fall back to the queued text, so an empty field genuinely means "empty."
The pack's own safety tip is the best one: connect Runtime Text Input into a Runtime Toggle String Join, keep that toggle OFF while you edit, and flip it ON when the text is ready. That way a half-typed edit never leaks into a queued job. For single-run workflows, this node's machinery buys you nothing - a plain multiline text node is simpler. It earns its keep on queues.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — | |
| state_key | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |