Nodes/ComfyUI-Drawer/Switch Chain (Drawer)
ComfyUI Node

Switch Chain (Drawer)

Last connected non-empty value wins

By Kuroi961·Created 5 months ago·Updated about a month ago· 5
Switch Chain (Drawer)
  • value_1
  • value_2
  • value_3
  • value_4
  • value_5
  • value_6
  • value_7
  • value_8
  • value_9
  • value_10
  • value_11
  • value_12
  • value_13
  • value_14
  • value_15
  • value_16
  • value_17
  • value_18
  • value_19
  • value_20
  • value_21
  • value_22
  • value_23
  • value_24
  • value_25
  • value_26
  • value_27
  • value_28
  • value_29
  • value_30
  • value_31
  • value_32
  • value_33
  • value_34
  • value_35
  • value_36
  • value_37
  • value_38
  • value_39
  • value_40
  • value_41
  • value_42
  • value_43
  • value_44
  • value_45
  • value_46
  • value_47
  • value_48
  • value_49
  • value_50
  • value_51
  • value_52
  • value_53
  • value_54
  • value_55
  • value_56
  • value_57
  • value_58
  • value_59
  • value_60
  • value_61
  • value_62
  • value_63
  • value_64
  • output

Sometimes you want a switch with no toggle: a row of optional upstream branches, and whichever one actually produced a value wins, in priority order. That's DrawerSwitchChain - up to 64 inputs, one output, and the rule is simple: the last connected non-empty value wins.

It's the sibling of DrawerSwitch in ComfyUI-Drawer, Kuroi's mobile-friendly drawer platform. Where DrawerSwitch is an A/B valve you flip, SwitchChain is a fallback ladder you wire and forget. There's no selector, nothing to click - the graph decides by which branches are live.

The mechanism

Inputs are value_1 through value_64, all optional, all typed * (any type). The node scans them from the highest number down - so value_64 has top priority - and returns the first one that is connected and non-empty. A string counts as empty if it's blank after stripping whitespace; other types just need to be present. If everything is empty or nothing is connected, it outputs None.

Here's the subtle part that's easy to trip on: this isn't "first non-empty wins" in the rgthree Any Switch sense - it's last wins, because scanning starts at the top of the numbering. If you only use value_1 and value_2, then value_2 wins whenever it has content, and value_1 is the fallback. That's intentional: it preserves the old A/B-switch meaning where the second input overrides the first. If you want something to be a higher-priority override, wire it into a higher-numbered slot.

A None output is a feature, not a bug - per the standard ComfyUI plumbing pattern, a deliberately-empty output feeding an optional input is exactly how you mute a branch from inside the data instead of bypassing nodes.

Installing it

cd ComfyUI/custom_nodes
git clone https://github.com/Kuroi961/ComfyUI-Drawer.git
pip install -r ComfyUI-Drawer/requirements.txt

Or search ComfyUI-Drawer in ComfyUI Manager. requirements.txt is just Send2Trash; no models, no extra system tools for the node itself.

Gotchas

  • Last non-empty wins, not first. This is the #1 confusion. Think "highest-numbered connected input that has a value", and wire priority accordingly.
  • Blank strings are skipped, so an upstream that outputs an empty prompt cleanly falls through to the next candidate. That's usually what you want.
  • It's a plain * node, so ComfyUI won't type-check the sockets - if you mix types (an IMAGE on value_3, a model on value_5), the node will happily return whichever wins and hand it downstream, where it may fail. Keep one type per chain.
  • If all inputs are empty you get None, which some downstream nodes reject and some treat as "unconnected". If a consumer chokes, that's the cause.

For workflows with several optional branches - "use the upscaled pass if it exists, otherwise the raw one, otherwise the placeholder" - this is a tidy single-node answer. Just remember which end of the chain has the authority.

CategoryDrawer

Inputs (64)

NameTypeDefaultDescription
value_1opt*
value_2opt*
value_3opt*
value_4opt*
value_5opt*
value_6opt*
value_7opt*
value_8opt*
value_9opt*
value_10opt*
value_11opt*
value_12opt*
value_13opt*
value_14opt*
value_15opt*
value_16opt*
value_17opt*
value_18opt*
value_19opt*
value_20opt*
value_21opt*
value_22opt*
value_23opt*
value_24opt*
value_25opt*
value_26opt*
value_27opt*
value_28opt*
value_29opt*
value_30opt*
value_31opt*
value_32opt*
value_33opt*
value_34opt*
value_35opt*
value_36opt*
value_37opt*
value_38opt*
value_39opt*
value_40opt*
value_41opt*
value_42opt*
value_43opt*
value_44opt*
value_45opt*
value_46opt*
value_47opt*
value_48opt*
value_49opt*
value_50opt*
value_51opt*
value_52opt*
value_53opt*
value_54opt*
value_55opt*
value_56opt*
value_57opt*
value_58opt*
value_59opt*
value_60opt*
value_61opt*
value_62opt*
value_63opt*
value_64opt*

Outputs (1)

NameTypeDescription
output*