Mute Bypass by ID — A/B
Flip one stage off and another on, automatically
The annoying thing about comparing two setups in ComfyUI isn't building them - it's that every test run means walking the graph and turning one thing off so the other can run. RemoteSwitch - "Mute Bypass by ID - A/B" - is a control node that makes this a single toggle: flip it one way and node A runs while node B is muted or bypassed; flip it back and the roles swap. Exactly one side is ever live, and you never touch the targets themselves.
That's the use case this node is for: two variants of the same pipeline stage. Two different ControlNets fighting for the same job, two upscalers you're judging, a refiner pass you want to A/B against a plain second pass. Rather than building two whole workflows or carefully muting one side per run, you point A and B at the two candidates and the switch keeps them mutually exclusive for you.
If you've used rgthree's group muting, the difference is worth naming: that mutes whole groups from a dashboard, which is great when your stages live in tidy groups. This takes the opposite approach - it targets individual nodes by ID, from wherever the control node happens to be, and it bakes in the "when A is on, B is off" logic so you can't forget it mid-run.
How it works
Like the rest of the pack, the Python side is a no-op - the entire mechanism is frontend JavaScript. The target_node_A and target_node_B fields become searchable pickers that list every node by ID and name, including nodes inside subgraphs (with the path shown so duplicate IDs between subgraphs don't confuse you). Each frame, the JS checks the switch_status toggle: if it's on, the A target gets mode 0 (running) and the B target gets the muted (mode 2) or bypassed (mode 4) state; if it's off, the two swap. The mode_select toggle just decides which of those "inactive" states the losing side gets.
The inputs that matter
Four fields; you set three of them:
target_node_A/target_node_B- the two pickers. Point them at your two candidates.switch_status- the A/B toggle. It's labeled "Side A Active" and defaults to on.mode_select- mute vs bypass for whichever side is losing. Bypass is the default, and it's usually what you want: the losing node is skipped but passes its upstream data straight through, so the graph never breaks.
There are no outputs and nothing to wire - this is a control node, not part of the data flow.
Installing it
One of five nodes in pixelpainter's mute-bypass by node ID pack - installing the pack brings all of them. No models, no dependencies. In ComfyUI Manager search for "mute-bypass by node ID", or:
cd ComfyUI/custom_nodes
git clone https://github.com/pixelpainter/comfyui-mute-bypass-by-ID
Restart ComfyUI afterward. The picker UI is frontend JS, so it simply won't exist until the web extension loads.
Gotchas
- The switch does not visually flip. This is a documented behavior change from the pack's V2.1.0 update - the A/B button keeps its color when you toggle it, on purpose, so the node reads as "still active" rather than "turned off." New users routinely think it's broken. It isn't; the active side is reflected in the targets' actual mute/bypass states.
- Mutually exclusive is the whole point. If you want both sides running at once, that's a different node - this one enforces one-or-the-other.
- Duplicate IDs across subgraphs: search by ID and see two matches? Check the path in the picker and pick the one in the subgraph you meant. Make sure you're on V2.0.0+ of the pack, where subgraph targeting got fixed.
It's a small node with one job, and it does that job in the exact way the "press a button to A/B a stage" workflow demands.
Inputs (23)
| Name | Type | Default | Description |
|---|---|---|---|
| mode_select | BOOLEAN | false | — |
| switch_status | BOOLEAN | true | — |
| target_node_A | STRING | — | |
| target_node_B | STRING | — | |
| suppress_enable | BOOLEAN | true | — |
| target_node_A2 | STRING | — | |
| target_node_B2 | STRING | — | |
| target_node_A3 | STRING | — | |
| target_node_B3 | STRING | — | |
| target_node_A4 | STRING | — | |
| target_node_B4 | STRING | — | |
| target_node_A5 | STRING | — | |
| target_node_B5 | STRING | — | |
| target_node_A6 | STRING | — | |
| target_node_B6 | STRING | — | |
| target_node_A7 | STRING | — | |
| target_node_B7 | STRING | — | |
| target_node_A8 | STRING | — | |
| target_node_B8 | STRING | — | |
| target_node_A9 | STRING | — | |
| target_node_B9 | STRING | — | |
| target_node_A10 | STRING | — | |
| target_node_B10 | STRING | — |
Outputs (0)
No outputs