CMK ControlNet Bypass Gate
The node that makes a ControlNet checkbox actually free
- PROCESS BYPASS
- IMAGE BYPASS
- LOG BYPASS
- PROCESS ACTIVE
- IMAGE ACTIVE
- LOG ACTIVE
- DIAGNOSTIC ACTIVE
- PROCESS
- IMAGE
- LOG
- diagnostic
Bypassing a node in ComfyUI is easy - you mute it in the UI. Bypassing a branch without paying for it is not, because ComfyUI still has to decide what a muted node's outputs are, and the lazy-input mechanism that makes real skipping possible is fiddly. CMK ControlNet Bypass Gate is the fiddly part, already written, with a boolean on the front.
What it is and who it's for
This is plumbing, and the pack says so: category CMK/Developer/Boundary & Cache, and the class carries a DEV_ONLY flag. You will never drag it onto a canvas from a tutorial. It's already sitting inside the shipped CMK workflows, where it's what turns the ControlNet module's ENABLE widget into something that costs nothing when it's off.
The value of that is bigger than one node's runtime. SDXL ControlNet checkpoints are 2.5GB files. Loading one for a run where ControlNet is disabled wastes seconds of disk I/O and a chunk of VRAM, and - worse in a modular pipeline - leaves a stale CONTROL_NET object sitting in an upstream cache that later modules have to reason about. The gate exists so the disabled path never produces that object at all.
How it works
The mechanism is lazy inputs, and it's the same trick the rest of the pack's boundaries use. Every optional input on this node is declared lazy, which means ComfyUI asks check_lazy_status before it evaluates anything upstream. The node looks at ENABLE and answers with exactly one thing: the name of the input it wants.
ENABLEisfalse→ it asks forPROCESS BYPASSandLOG BYPASSonly. The entire active ControlNet chain - model load, preprocessor, the lot - is never evaluated. The bypass inputs pass through untouched: same PROCESS, same IMAGE, same LOG.ENABLEistrue→ it asks forPROCESS ACTIVE,LOG ACTIVEand thenDIAGNOSTIC ACTIVE, and passes that set through instead.
Two details that look like trivia and aren't. First, IMAGE is deliberately not in the required-wait list, because a text-to-image run legitimately has no image yet; PROCESS and LOG are the authoritative proof that a branch actually ran. Second, when the module is disabled the diagnostic output is filled with an ExecutionBlocker, so nothing downstream can render or consume a diagnostic that never happened.
You feed it three inputs and get four outputs: a PROCESS (CMK_PROCESS_SDXL), an IMAGE, a LOG, and the diagnostic. Wire the outputs into whatever the next module in the chain reads.
Install
Manager: search CMK Flow, install the CMKFlow entry, restart - the gate arrives with the pack. Manually:
git clone https://github.com/CMKFlow/cmk_nodes.git custom_nodes/cmk_nodes
python3 custom_nodes/cmk_nodes/scripts/install_cmk_requirements.py
CMK dependency check: OK is your green light. If you keep a shared model directory, python3 custom_nodes/cmk_nodes/scripts/check_cmk_resources.py --models-root "/path/to/shared/models" audits the exact files the reference workflows expect. CMK is a one-author GPL-3.0 pack by Carsten Kirschner, open-sourced in July 2026 - it's real software with real code behind it, not a wrapper, but the community footprint is tiny, so you'll be reading the source more than the forum threads when something misbehaves.
Issues worth knowing
This node raises instead of guessing. If the branch it selected hands back a None PROCESS or LOG, you get a plain ValueError naming which side is missing - "CMK ControlNet Bypass Gate is missing the BYPASS result." That almost always means a genuinely unwired input on one of the two paths, not a bug: the gate needs both legs connected, the active one and the bypass one, even though only one will run.
And if you're building a workflow by hand, wire the bypass leg to the same PROCESS and IMAGE that come into the module. The gate doesn't invent a fallback; it selects. There's no passthrough magic inside it.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| ENABLE | BOOLEAN | false | — |
| PROCESS BYPASSopt | CMK_PROCESS_SDXL | — | |
| IMAGE BYPASSopt | IMAGE | — | |
| LOG BYPASSopt | CMK_LOG_PIPE | — | |
| PROCESS ACTIVEopt | CMK_PROCESS_SDXL | — | |
| IMAGE ACTIVEopt | IMAGE | — | |
| LOG ACTIVEopt | CMK_LOG_PIPE | — | |
| DIAGNOSTIC ACTIVEopt | CMK_DIAGNOSTIC | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| PROCESS | CMK_PROCESS_SDXL | — |
| IMAGE | IMAGE | — |
| LOG | CMK_LOG_PIPE | — |
| diagnostic | CMK_DIAGNOSTIC | — |