Switch Chain (Drawer)
Last connected non-empty value wins
- 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 onvalue_3, a model onvalue_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.
Inputs (64)
| Name | Type | Default | Description |
|---|---|---|---|
| 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)
| Name | Type | Description |
|---|---|---|
| output | * | — |