Lazy Switch 3 Values (obvpm)
Three wires, one boolean, none of the wasted work
- on_false_value_1
- on_false_value_2
- on_false_value_3
- on_true_value_1
- on_true_value_2
- on_true_value_3
- value_1
- value_2
- value_3
There's a specific number that keeps showing up when you split a ComfyUI graph in two: three. A model load comes back as MODEL, CLIP and VAE. A sampling stage hands over a latent, a mask and a seed. An upscale branch returns an image, its mask and the scale factor you used. Splitting the graph with three separate Lazy Switches means three copies of the same boolean and three chances to wire one of them backwards.
Lazy Switch 3 Values (obvpm) gangs them. One boolean, three slots, all three flip together - and only the selected side executes.
Inputs and outputs
boolean- required BOOLEAN, default true. True takes theon_true_value_*block, false takeson_false_value_*.on_true_value_1/2/3andon_false_value_1/2/3- optional wildcard inputs, up to three per side.value_1,value_2,value_3- the selected side's values, positionally matched.
Slots are type-blind (*), so value_1 could be an IMAGE on the true side and a LATENT on the false side. That's flexibility, and it's also how you end up with a type error two nodes downstream instead of at the switch. Keep the slots semantically parallel: slot 1 is always the same kind of thing on both sides.
Unconnected slots on the selected side output None - no error. Half-built workflows still queue.
Laziness is the feature, not a bonus
The unselected side is never executed, because the switch's inputs are declared lazy and it explicitly asks the engine for one side only. Feed the false side a whole second pipeline - different checkpoint, different LoRA chain, its own samplers and upscalers - and flipping the boolean means that entire pipeline costs zero seconds and zero VRAM.
This is the thing the pack's own README is careful about: mute and bypass both act downstream of a gate, and only lazy evaluation saves the upstream work. If what you want is a graph where one branch genuinely doesn't exist today, laziness is the mechanism that delivers it - and this node is one boolean away from being a two-in-one workflow.
A pleasant side effect: a branch that was killed by an optional gate in mute mode can be brought back by selecting the other side. The mute blocked the path, it didn't damage the nodes.
The standard pairing is a gate's present output driving boolean, so the switch decides itself based on whether an optional input exists. Reference image present → reference pipeline. Absent → base pipeline. No manual toggling, no second workflow.
Three values or two?
If slot 3 is routinely empty, use Lazy Switch 2 Values - fewer sockets, less to misread. Three-slotters earn their keep when the group is genuinely a triple: MODEL/CLIP/VAE, latent/mask/seed, or image/mask/scale. When the values stop being a group and become two independent decisions, split them into two switches; a shared boolean is only a convenience while the things it controls actually belong together.
Install
ComfyUI Manager → search comfyui-obvpm, or:
cd ComfyUI/custom_nodes
git clone https://github.com/chanon/comfyui-obvpm
Restart ComfyUI. It shows up under obvpm/switches, and a node-menu search for obvpm reveals the rest of the pack. No Python dependencies, nothing to download; the pack's pyproject.toml is deliberately empty. The (obvpm) suffix on every class id arrived in 0.2.0 to resolve a collision with another pack's Bundle node, and pre-0.2.0 workflows are migrated on open.
Traps
Output nodes ignore laziness. If the dead side ends in a Save Image or Preview, it runs anyway: every OUTPUT_NODE is an execution root, so there's no wire to prune. Gate that branch with the pack's Mute node if it must not fire.
A lazy switch is not a data merge. It picks a side; it never combines them. If you want "whichever of these exists", that's First Float / First Int or an optional gate, not this.
One boolean, no exceptions. There's no per-slot override. If slot 2 needs to come from the other side while slots 1 and 3 stay put, you wanted two switches.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| boolean | BOOLEAN | true | Selects which side to execute and output: true = the on_true_value inputs, false = the on_false_value inputs. |
| on_false_value_1opt | * | Output as value_1 when boolean is false. Only executes while selected; may be left unconnected. | |
| on_false_value_2opt | * | Output as value_2 when boolean is false. Only executes while selected; may be left unconnected. | |
| on_false_value_3opt | * | Output as value_3 when boolean is false. Only executes while selected; may be left unconnected. | |
| on_true_value_1opt | * | Output as value_1 when boolean is true. Only executes while selected; may be left unconnected. | |
| on_true_value_2opt | * | Output as value_2 when boolean is true. Only executes while selected; may be left unconnected. | |
| on_true_value_3opt | * | Output as value_3 when boolean is true. Only executes while selected; may be left unconnected. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| value_1 | * | The selected side's value for this slot. None when that slot is unconnected. |
| value_2 | * | The selected side's value for this slot. None when that slot is unconnected. |
| value_3 | * | The selected side's value for this slot. None when that slot is unconnected. |