Runtime Toggle String Join (3)
Three live toggles for long queues — Runtime Toggle String Join (3)
- text
The Runtime Toggle String Join family exists for one scenario: you've queued a long batch and you still want a hand on the wheel. Where the plain Toggle joins freeze their state at queue time, these read the latest live state at the moment each job executes. Runtime Toggle String Join (3) is the three-input version - enough room for a subject, a style, and a scene, each with a toggle you can flip between queued jobs.
Here's how it reads in practice. You queue thirty jobs. Job 7 generates. While it runs, you decide the style branch isn't working, click its toggle off, and click another on. Job 8, and every job after, uses the new composition - no re-queueing, no reloading the workflow. The status area shows LIVE and the node carries a faint amber tint so you can tell at a glance it's the live variant and not the snapshot one.
The mechanism, briefly
Each toggle click pushes the new mode and mask to a small state store on the ComfyUI server, keyed by state_key. At execution time the node reads that live state - not the queue-time snapshot - and joins only the enabled non-empty strings. Live state missing (say, after a restart) means it falls back to the saved values. Two things follow from the implementation, and both are worth expecting:
- The node folds a monotonic revision number into
IS_CHANGED, so changing a toggle invalidates the cached result and forces a re-execution. Flip a toggle and it actually takes effect, which is the whole reason it feels "live." - Timing is "the next image onward": a change lands on jobs that haven't executed the node yet, so don't expect the currently-generating image to reflect a mid-run click.
The README also flags browser behavior: live state is shared by state_key on the server, so run one active browser tab per workflow - a second tab holding the same key can overwrite your clicks.
The controls
mode-multiple(each input independent) orsingle(zero or one enabled).- Per-row ON/OFF buttons - the interface you'll actually use.
separator- default", ", with\n,\r\n,\t,\\escapes.state_key- auto-generated per node; leave it alone unless you deliberately want copies to share live state.text_1…text_3- optionalSTRINGsockets. Output: onetextSTRING.
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. Zero Python dependencies, no models. Under String Join Tools.
When to skip it
Honestly? If you're not running multi-job queues, this node's live-state machinery buys you nothing - the plain Toggle Join (3) gives identical output for a single run with a simpler mental model. The runtime family is specialized hardware. Reach for it when the batch is long enough that re-queueing would be a real cost, and remember the live state is in-memory: a server restart wipes it, and you're back to fallback values until you nudge a toggle.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| separator | STRING | , | Supports \n, \r\n, \t, and \\. |
| mode | COMBO | multiple | 2 options: multiple, single |
| enabled_mask | INT | 70–7 | — |
| selected_index | INT | 0-1–2 | — |
| state_key | STRING | — | |
| text_1opt | STRING | Optional queued STRING input. Its generated value is accepted or rejected at execution time by the live toggle. | |
| text_2opt | STRING | Optional queued STRING input. Its generated value is accepted or rejected at execution time by the live toggle. | |
| text_3opt | STRING | Optional queued STRING input. Its generated value is accepted or rejected at execution time by the live toggle. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |