Execution Gate Controlboard
One Switchboard for Every Branch You Keep Turning Off by Hand
Any workflow past twenty nodes ends up with branches you don't always want. The refiner you only run when the base render is soft. The save node you turn off for testing. The usual fix is right-click → bypass, twice a day, on a node buried three screens to the left.
Execution Gate Controlboard is the pack's answer: one node that lists every Execution Gate and Any Gate in the graph, with a switch on each. It has no inputs, no outputs, and no effect on your run. It's a panel, and that's the point.
The gates it's built around
A WASExecutionGate passes a value on while its open switch is on. Switched off, it doesn't just skip itself: its value input is lazy, so the branch feeding it is never evaluated and every node after it stops. That's the difference from muting a node - a bypassed sampler still has its inputs computed upstream; a closed gate means the sampler and the save don't run at all.
The nearest thing elsewhere is rgthree's Fast Groups Muter and Bypasser, which do this at group level by flipping nodes in and out of bypass. A gate is wiring rather than decoration: it stops evaluation, and it's per-branch instead of per-label. Which makes open the one switch per branch worth a handle on - and a big workflow has a dozen of them.
How the panel works
There is nothing to run. execute() returns an empty result; the backend half of this node exists to give the frontend somewhere to draw.
The behaviour lives in a frontend script that walks the root graph and every subgraph under it, collecting nodes of type WASExecutionGate and WASAnyGate. Each row shows the gate's title, path-prefixed with its subgraph, plus its kind and node id - gate #41 - because two gates can share a title.
The clever part is what the switch writes to. It keeps no copy of anything: it reads and writes each gate's own open widget and calls that widget's callback, exactly as if you'd clicked it on the gate. The setting still belongs to the gate, so it survives a save, an undo, and a copy-paste - no second source of truth to drift. The header chip cycles row order between Graph, Name and Position; the footer carries "All open" and "All closed" beside a count like 3 of 7 open, which excludes wired gates. That's the trap.
How to use it
Drop your gates where the branches start, then one controlboard wherever you can see it. The gates work without the panel; the panel is just a place to stand.
A gate whose open is wired - driven by a Compare node, a boolean, anything the graph works out - is listed as wired, with a disabled row and no switch. That's correct, not a bug: if the graph decides the gate, a manual toggle would be a lie. Any Gate is the conditional cousin: same blocking behaviour, but its open comes from a condition you compute, and it's the one people reach for when a branch should only run sometimes.
Set closed_message on gates you'll switch off in normal use. Empty stops the run quietly, right for a routine skip. Any text - no face found, nothing to upscale - is drawn on the first blocked node as an error and raised as a notification, which is what you want when a branch you expected to run didn't.
Installing it
ComfyUI Manager, search WAS Node Suite v3, install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/was-node-suite-comfyui.git
That's the whole install - nothing is pip-installed, downloaded or built, now or on later starts. You need ComfyUI 0.14.0 or newer and Python 3.10+. The first start after an install or update takes a couple of seconds longer while the pack compiles and writes its config.yaml. The frontend half loads at startup, so a fresh install needs the restart, not a page refresh.
Where people get burned
The panel says "No gates in the graph". Correct - it lists gates, not switch nodes generally. Add an Execution Gate or Any Gate first.
A gate on the canvas isn't in the list. Either it isn't one of the two gate types, or the walker didn't reach it. Gates inside subgraphs are listed, so check the row label for a subgraph prefix before assuming it was skipped.
Old tutorials tell you to install requirements, then core nodes break. That's v2 advice. V2 shipped packages and renamed nodes into collisions with core - a 2026 thread exists from someone whose default Load Image "got overwritten". V3 installs nothing and renamed the three clashing labels (KSampler → KSampler (Seed Socket), Seed → Seed (Number Outputs), Save Video → Save Video (Advanced)).
The pack doesn't load on an older ComfyUI. V3 needs 0.14.0+ and won't show up at all until you update. Confirm the startup log names the pack, then retry.
Inputs (0)
No inputs
Outputs (0)
No outputs