Lazy Switch (obvpm)
Pick a branch, and don't pay for the other one
- on_false
- on_true
- value
This is the node people mean when they say "lazy switch." Ask r/comfyui how to conditionally route a workflow down one path or another - as one poster did in September 2025, tired of hand-bypassing groups - and the top answer is "lazy switch from kjnodes." KJNodes' version became the standard answer because it does the one thing ComfyUI's ordinary bypass can't: it stops the unselected branch from running at all.
The obvpm version is the same idea with the pack's gates to drive it. Two inputs, a boolean, and - this is the whole value proposition - the branch you didn't pick never executes, so nothing feeding it costs you anything.
What it does
boolean picks the side. True, you get on_true on the value output; false, on_false. Both sides are optional, and the selected side being unconnected isn't an error: you get None, quietly. That's deliberate - it means a switch sitting on a branch that's off doesn't detonate the run.
The laziness is real, not marketing. Both inputs are declared lazy, and the node's check_lazy_status tells the engine which one to evaluate - only the selected side is ever requested, so the entire upstream chain of the other side is skipped before anything in it is computed. There's one subtlety in there that explains a class of bug you'll otherwise spend an hour on: requesting a lazy input that has no link is a hard engine error, so the node checks whether the selected pin is actually connected before asking for it. That's why an empty selected side gives you None rather than a crash.
Inputs and outputs
boolean- the selector. A widget by default, but connectable, which is the point: it can be driven by logic rather than your mouse.on_false/on_true- the two branches. Optional, untyped wildcards.- Output:
value, the selected side's value, orNoneif that side is empty.
The wiring this node is built for
Feed boolean from a gate's present output. That output is a boolean that's true when the gate's input was connected, and it stays live even when the gate is muting its value path - so you get "run the reference branch if a reference image was loaded, otherwise run the from-scratch branch" with no manual step and no duplicated graph.
The other half of that trick: a branch that a gate has muted can be picked back up. Select the other side and the workflow continues, because the blocker was only ever on the value path that got skipped.
The thing laziness cannot do
Here's the caveat that costs people whole afternoons, and the pack's README is refreshingly blunt about it. Laziness prunes upstream: the unselected branch's nodes never run. It cannot prune output nodes. A Save Image, a Preview, a video-save - every OUTPUT_NODE is an execution root, so ComfyUI works backwards from it and nothing reaches it "through a wire" that can be pruned. If a save node is fed from anywhere, it runs.
The mirror image is just as common. A gate's mute (an ExecutionBlocker) stops everything downstream but saves none of the upstream compute, because by the time an eager input can be objected to it's already been computed.
So switching a branch off completely needs both: laziness to stop the work, a blocker to stop the sink. Which half you're missing is the single most common misdiagnosis in this corner of ComfyUI, and the plumbing notes on the wider ecosystem's switch-and-mute nodes make the same point from the other direction.
Install
Manager, search comfyui-obvpm, or:
cd ComfyUI/custom_nodes
git clone https://github.com/chanon/comfyui-obvpm
Restart. No Python dependencies - the pack's pyproject.toml declares none on purpose, because everything it imports already ships with ComfyUI - and no model files. Search obvpm in the node menu; every node in the pack carries that suffix in its display name. There's no community thread to read about this pack (the reddit corpus has zero mentions of it), so the source is the documentation. It's short.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| boolean | BOOLEAN | true | Selects which side to execute and output: true = on_true, false = on_false. |
| on_falseopt | * | Output when boolean is false. Only executes while selected; may be left unconnected. | |
| on_trueopt | * | Output when boolean is true. Only executes while selected; may be left unconnected. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| value | * | The selected side's value. None when the selected side is unconnected. |