Nodes/ValiTools/VRandomSelector
ComfyUI Node

VRandomSelector

Pick one input at random — and only that branch actually runs

By vangel76·Created 2 months ago·Updated 8 days ago· 1
VRandomSelector
  • input_1
  • input_2
  • input_3
  • input_4
  • input_5
  • input_6
  • input_7
  • input_8
  • input_9
  • input_10
  • input_11
  • input_12
  • input_13
  • input_14
  • input_15
  • input_16
  • input_17
  • input_18
  • input_19
  • input_20
  • input_21
  • input_22
  • input_23
  • input_24
  • input_25
  • input_26
  • input_27
  • input_28
  • input_29
  • input_30
  • selected
  • selected_index
◄seed0►
◄from_input0►
◄to_input0►

What it is

VRandomSelector passes one of its connected inputs through at random. Sounds trivial - and it is, mechanically - but the lazy evaluation is the entire reason to use it: only the selected input's upstream branch executes. The branches you didn't pick stay completely cold. That's the difference between "roll a dice to choose which LoRA" and "silently run every LoRA you rolled against".

Why the laziness matters

A plain switch node computes both sides and picks at the end. If your two inputs are two different upscalers, two LoRA stacks, or two checkpoint-heavy prompt branches, "compute both" means paying double the VRAM and time on every queue, even though you only keep one. VRandomSelector asks ComfyUI's execution engine to run exactly the branch it picked. So it's the node you reach for when the choice is random but the cost of the unchosen branch isn't something you want to pay. It slots into the same family as switch nodes and the *-typed ANY sockets that plumbing doc loves - the type system's escape hatch that lets one node route anything.

A common use: hook a few LoraLoaders in front of it and let the selector flip which LoRA applies per queue, for cheap style variety in a batch - the unchosen LoRAs never even load.

How it works

Under the hood it's a ComfyUI wildcard-type node: every input socket is declared as * (accepts any type) and VALIDATE_INPUTS returns True so the backend skips type-checking. The first connection locks the type - all inputs must share one type, and mixing an IMAGE with a LATENT in the same selector is a no. A new empty input slot appears as you connect, up to 30. The frontend grows the list, and check_lazy_status tells the engine which single input it needs this run, so everything else upstream stays unexecuted.

The pick is pure: seed + the set of connected inputs determines the choice, so the same seed with the same connections always picks the same slot. from_input and to_input restrict the pick to a slot range (0 = no limit, so leave them at 0 unless you have a reason).

Inputs: seed, from_input, to_input, and input_1 through input_30. Outputs: selected (typed like your inputs) and selected_index (1-based).

Installing

Install via ComfyUI Manager (search "ValiTools" or "comfyui-ValiTools"), or clone it:

cd ComfyUI/custom_nodes
git clone https://github.com/vangel76/comfyui-ValiTools

Then restart ComfyUI. No pip install, no model files - this node is just Python and a bit of frontend JS.

Common issues

  • "no connected input in range" - your from_input/to_input are excluding every slot you actually wired. Both default to 0 (no limit); only touch them if you deliberately want to restrict which slots participate.
  • The type is locked by the first connection. Connect an IMAGE first and you can't add a LATENT input. If you need to switch between different types, this isn't the node - you want a typed switch or a different approach, because this one commits to one type.
  • Same seed, different pick? Check that the set of connected inputs actually matches - an empty slot that looks connected can change the pool. The pick is deterministic over seed + connected set.
  • selected_index is 1-based, and it indexes the physical slot, not the filtered position. If you restrict with from_input, the index still reports the real slot number - wire it somewhere that expects the actual slot, not the "rank" within the range.
CategoryValiTools

Inputs (33)

NameTypeDefaultDescription
seedINT00–18446744073709550000Same seed with the same connected inputs always picks the same one. Keep it on 'randomize' for a new pick each queue.
from_inputINT00–30Restrict the pick to inputs numbered from this one on. 0 = no lower limit.
to_inputINT00–30Restrict the pick to inputs numbered up to this one. 0 = no upper limit.
input_1opt*—
input_2opt*—
input_3opt*—
input_4opt*—
input_5opt*—
input_6opt*—
input_7opt*—
input_8opt*—
input_9opt*—
input_10opt*—
input_11opt*—
input_12opt*—
input_13opt*—
input_14opt*—
input_15opt*—
input_16opt*—
input_17opt*—
input_18opt*—
input_19opt*—
input_20opt*—
input_21opt*—
input_22opt*—
input_23opt*—
input_24opt*—
input_25opt*—
input_26opt*—
input_27opt*—
input_28opt*—
input_29opt*—
input_30opt*—

Outputs (2)

NameTypeDescription
selected*—
selected_indexINT—