Optional Any (obvpm)
The gate for a wire that might not be there
- input
- value
- present
You know the drill. You built a workflow that takes a reference image sometimes. When you don't load one, ComfyUI doesn't thank you for your flexibility - it either errors three nodes deep about a required input, or it quietly runs the whole reference branch against an empty wire and hands you a mushier image for reasons you don't spot until you compare seeds. So you start bypassing nodes by hand before each run, and then you forget once.
Optional Any is the node that ends that. It's a wildcard gate: the input is optional, and you decide what "no input" means downstream.
What it actually does
Wire anything into input and it comes out of value unchanged. Leave input unconnected and on_empty picks the behaviour:
mute(the default) - the node emits ComfyUI'sExecutionBlocker, and every node downstream of it is silently skipped.bypass- it forwardsNone, and a downstream node with an optional input treats that as unconnected and decides for itself.
The second output is present, a BOOLEAN that is true when something is wired in. Here's the part worth internalising: present stays live even in mute mode. The value path dies, the flag doesn't. That's what lets you drive a Lazy Switch off "do I have a reference image this run?" without the boolean itself getting blocked along with the image.
The source makes this a two-line decision, which is why it's cheap to reason about:
if input is None and on_empty == "mute":
return (ExecutionBlocker(None), False)
return (input, input is not None)
The inputs and outputs that matter
on_empty is the only knob (mute / bypass), and input is the only socket going in. Out the other side: value (the wildcard passthrough) and present (the boolean). That's the whole node. There is nothing else to configure, which is the point - this is plumbing, not a feature.
Typical wiring: gate a reference image, take value onward into your IP-Adapter or in-context reference branch, and take present into a Lazy Switch's boolean so the branch that expects the reference only runs when it exists.
Where people get burned
bypass is not "safe", it's "deferred". Feeding None into a required input is still an error, just a later and more confusing one. Bypass only works when the consumer declares the input optional. If your graph explodes at the consumer, you wanted mute.
mute cannot be caught. A blocker propagates - nothing downstream gets a chance to object or recover. And the reverse caveat bites too: mute stops everything downstream of the gate, but the nodes upstream of input still ran and already cost you the time. Only a lazy node saves upstream compute (see the pack's Lazy Switch nodes).
It's * typed, so nothing checks you. The wildcard is ComfyUI's one escape hatch from its type system - the docs' own framing is that it's then "up to the node to make sense of the data passed." A wildcard gate in the middle of a graph is a wire the editor can no longer help you validate. Use one where you genuinely don't know the type; if you know it's an image, Optional Image is the same node with a type on it, and it will catch a miswire for you.
Nothing in this pack has community lore to lean on. Searching the reddit corpus for "obvpm" returns zero threads - no drama, no testimonials, nothing. That's not a red flag, it's just a young single-author pack, so judge it on reading the source, which is short and legible.
Installing it
Through ComfyUI Manager, search the pack title comfyui-obvpm, or do it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/chanon/comfyui-obvpm
Restart ComfyUI. There are no extra Python dependencies - the pack's pyproject.toml deliberately declares none, because everything it imports (torch, numpy, PIL, av) already ships with ComfyUI's own requirements. No model downloads either. Every node in the pack is suffixed (obvpm) in the menu, so typing obvpm in the node search lists them all.
The repo moved from obvpm/comfyui-obvpm to chanon/comfyui-obvpm; if you're following an older link, that's the same pack under the author's own name.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| on_empty | COMBO | mute | What downstream sees when no input is connected: mute skips every downstream node, bypass outputs None. |
| inputopt | * | The value to pass through. May be left unconnected. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| value | * | The input passed through. When the input is empty: blocked (mute) or None (bypass). |
| present | BOOLEAN | True when an input is connected. Stays live even in mute mode. |