First Float (else fallback) (obvpm)
Take the first value that shows up, or the fallback
- float
Optional branches are great right up until they reconverge. You've got three ways a denoise strength can arrive - a preset bundle, an override node, a hand-set value - and whichever one is live this run needs to end up in the sampler's denoise input. ComfyUI has no built-in "use whichever of these exists" socket, so you end up rewiring before each run, or duplicating the whole downstream half of the graph.
First Float is that socket. Three candidate inputs, a fallback, one guaranteed output.
What it does
It walks float1, float2, float3 in pin order - not graph order, not execution order, just 1 → 2 → 3 - and returns the first one that isn't None. If all three are empty, you get the fallback widget value you typed. The output is a single float.
for i in range(1, 4):
value = values.get(f"float{i}")
if value is not None:
return (value,)
return (fallback,)
That's the whole mechanism, and the reason it works with this pack's gates specifically: an optional gate in bypass mode outputs None, so a gated branch that isn't live simply gets skipped over as if it had never been connected. Three optional paths fan into one value with no logic and no selector to set.
The candidates are forceInput, which is a detail you'll notice immediately: float1–float3 are sockets only. You can't type a number into them - converted widgets they are not. Only fallback is a widget, and it's always there as the floor.
Where people get tripped up
Pin order, not priority-by-source. If float1 is connected and carrying 0.4, and float2 is carrying the value you actually wanted, you get 0.4. There's no "most recent wins" or "prefer non-default" logic. Rearranging which gate feeds which pin is how you set precedence, so pick an order and keep it.
Zero is a value. 0.0 is not None and will win the walk. That's correct behaviour, but it means you can't use "0" as a sentinel for "not set here" - the first pinned 0.0 beats everything to its right.
It only takes floats. The type is checked like any other socket; wiring an integer output in is fine where ComfyUI can coerce it, but a LATENT will bounce. If you need an integer, there's First Int alongside it.
It is a fallback switch, not an A/B switch. This distinction catches people coming from other packs. An A/B switch has a selector you set; a fallback switch has none and the graph decides. The plumbing docs describe rgthree's Any Switch as the canonical version of this shape - "chooses the first input that is not null/empty" - and that's exactly what you're holding, except typed to FLOAT, capped at three candidates, and with an explicit floor value instead of a None output. Three is plenty for most fan-ins, and the fallback widget is the nicer trade: downstream never has to handle None.
The setup it's actually for
Build a workflow where a value can come from anywhere. Drive each path through a gate, wire the gate outputs into float1..3, set fallback to a sane middle-of-the-road number, and run. On a run where nothing is wired in, the fallback keeps the graph alive; on a run where two things are wired in, the earlier pin wins and you don't get a surprise.
That's it - the node is ten lines of code and does one thing. It earns its place by removing the rewiring step, not by being clever.
Install
Manager, search comfyui-obvpm. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/chanon/comfyui-obvpm
Restart ComfyUI. No dependencies, no models - the pack ships pure Python plus its frontend JavaScript, and declares no packages of its own. Search obvpm in the node menu and you'll see all of them.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| fallback | FLOAT | 0.00-1000000000000000000–1000000000000000000 | Output when none of the inputs carry a value. |
| float1opt | FLOAT | Candidate 1: used when it is the first connected input with a value. Bypassed (None) inputs are skipped. | |
| float2opt | FLOAT | Candidate 2: used when it is the first connected input with a value. Bypassed (None) inputs are skipped. | |
| float3opt | FLOAT | Candidate 3: used when it is the first connected input with a value. Bypassed (None) inputs are skipped. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| float | FLOAT | The first connected input that has a value, or the fallback. |