First Valid
Default Images, Prompts, and Params Without a Switch in Sight
- first
- second
- third
- output
Every good workflow eventually needs a fallback. A default image when the optional input is empty, a default prompt when the generator is offline, a default seed when nothing's wired. You can build that with a pile of switches, or you can use First Valid, which does what its name says: it walks its inputs in priority order and passes through the first one that isn't falsy. No selector widget, no deciding - the graph decides for you.
This is the "first-non-null" fallback pattern that's been a ComfyUI staple since rgthree's Any Switch. Where that node takes any number of inputs, First Valid fixes it at three - first, second, third - and, crucially, wires in lazy evaluation so a missing input doesn't break anything downstream.
How it works
All three inputs are the * (any-type) wildcard: they accept an image, a latent, a string, a model, anything. The node checks first, then second, then third, and returns the first truthy one through its single output. "Truthy" here means non-None, non-zero, non-empty - an empty string or a zero count counts as "not valid," which is usually what you want from a fallback.
The mechanism worth appreciating is lazy evaluation. The node requests inputs one at a time, in priority order, and only pulls the next one if the current one came back falsy. So when first is a live, connected value, the node never evaluates the second and third branches. That's not a micro-optimization - it means you can hang expensive generation nodes (a whole image pipeline) off second and they simply won't run while first works. If all three are falsy, the node blocks execution via ComfyUI's ExecutionBlocker rather than passing along garbage.
The inputs are optional, and an unconnected input arrives as None - which is exactly the convention this node is built on. That's the pattern in practice:
first- the "real" value (your live input, a loader, whatever the workflow normally uses).second- a cached or default value for when the primary is empty.third- the absolute fallback, often a hardcoded default.
Typical setup: wire an optional reference image into first, a "default.jpg" loader into second, and let the graph quietly fall back whenever the reference isn't provided. Same trick works for prompts, seeds, and parameters - any type, because the sockets are polymorphic.
Install
Search "Trent Nodes" in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/TrentHunter82/TrentNodes.git
cd TrentNodes
pip install -r requirements.txt
Pure logic, no models. Restart ComfyUI after installing. (Manager can be flaky on this pack - the author has noted an early repo rename left a duplicate registry entry - so manual clone if it errors.)
Common issues
- Everything falls to
thirdand you don't know why.firstwas truthy-but-wrong, orsecondwas wired but returned empty. Check what's actually connected - an unconnected slot reads asNone, which is "falsy," so a missing wire silently cascades down the chain. - "It's not a switch." Right - there's no selector. If you want to choose between branches manually, you want an A/B switch, not a fallback. First Valid is for "let the data decide."
- A branch that shouldn't run is running. Lazy evaluation only skips inputs when an earlier one is truthy at execution time. If you're seeing spurious evaluation, something earlier in the chain is returning a falsy-but-not-None value (like an empty string).
For "give me a default when nothing else is there," it's three inputs and one output, and it'll save you a switch node and a headache. If your workflow already depends on fallbacks, this is the clean way to express them.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| firstopt | * | Highest priority input - checked first | |
| secondopt | * | Second priority - used if first is falsy | |
| thirdopt | * | Third priority / fallback - used if first and second are falsy |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| output | * | — |