Nodes/String Join Tools/Optional String Join (2)
ComfyUI Node

Optional String Join (2)

Two prompts that never argue — Optional String Join (2)

By ruminar·Created 2 months ago·Updated 27 days ago· 2
Optional String Join (2)
    • text
    separator,
    text_1
    text_2

    Optional String Join (2) is the smallest node in ruminar's String Join Tools pack: two string sockets in, one string out, with a separator widget between them. Nothing else. It looks almost too simple to bother with - until you've watched a plain Text Concatenate node vomit ", , " because one of its inputs came back empty.

    That's the whole point. The two text inputs are optional sockets, not type-in fields. Leave one unconnected and it's ignored. Connect something that resolves to an exact empty string and it's ignored too. The separator only appears between strings that actually exist, so "a" + "" + "b" gives you "a, b", not "a, , b". If both inputs are missing or empty, you get "" back, clean and simple.

    Where you'd actually use it

    Prompt assembly is the obvious home. Wire a base subject into text_1 and a style or quality suffix into text_2, feed the output into your CLIP Text Encode, and you've got a two-part prompt you can edit in one place. The forgiving part is what makes it useful in bigger graphs: if that style branch comes from a wildcard picker or a LoRA trigger node that only fires sometimes, an empty result just vanishes instead of corrupting the whole prompt with a stray comma.

    It's also handy for building filename or metadata fragments - prefix plus suffix - when either half might be absent.

    How it works

    Under the hood it's dead simple and that's a feature. text_1 and text_2 are declared as optional STRING inputs with forceInput, so they're wire-only sockets; you can't type into them, and an unconnected optional input simply doesn't get passed to the node's function. The code filters out anything that isn't a string or is exactly "", keeps whitespace-only strings and embedded line breaks intact, then joins what's left in socket order with the decoded separator.

    One detail worth knowing: the separator field supports a few escapes, since you can't always press Enter inside a one-line widget. Type \n for a line feed, \r\n for a Windows newline, \t for a tab, \\ for one backslash. Unsupported sequences like \u or \x are left exactly as you typed them.

    Installing it

    Both paths work, and neither downloads anything heavy - this pack has zero Python dependencies and no model files:

    • ComfyUI Manager: search "String Join Tools" or "ComfyUI-StringJoinTools", install, restart, refresh the browser.
    • Manual: cd ComfyUI/custom_nodes && git clone https://github.com/ruminar/ComfyUI-StringJoinTools, restart ComfyUI, refresh the page.

    You'll find the node under the String Join Tools category.

    Where people trip up

    The escape sequences trip everyone once. A literal backslash in front of an n is a newline; if you actually want the two characters \n in your output, type \\n. And remember the inputs are sockets, not text boxes - if you're trying to type a fixed string into this node, you want a PrimitiveString or a plain text node feeding it instead. Both facts take about thirty seconds to learn and save you a confused afternoon.

    Need three, five, or ten inputs? The same pack has Optional String Join (3), (5), and (10), and you can chain joins in stages if you ever outgrow even those.

    CategoryString Join Tools

    Inputs (3)

    NameTypeDefaultDescription
    separatorSTRING, Inserted only between usable strings. Supports \n, \r\n, \t, and \\.
    text_1optSTRINGOptional STRING input. Missing inputs and exact empty strings are ignored.
    text_2optSTRINGOptional STRING input. Missing inputs and exact empty strings are ignored.

    Outputs (1)

    NameTypeDescription
    textSTRING