Latent QC Gate π§
The Night-Watch Gate That Stops a Corrupted Latent Before It Costs You a Run
- latent
- fallback_latent
- latent
- passed
- reason
You've queued a 500-image batch and gone to bed. At 3am one of them samples into a wall of NaN static, and the queue happily decodes it, saves it, and moves on. That's the failure mode Latent QC Gate exists to catch: an automated PASS/FAIL check on the latent itself, before VAE decode, with an optional fallback so the run doesn't die. It's the only thing in the pack that checks a LATENT tensor before it reaches VAEDecode - everything else assumes the sampler did its job. This node is the QA shift for your unattended renders.
How it works
Three independent checks, each toggleable:
- check_nan_inf - flags NaN or infinity values. The nuclear failure; if you see this, something upstream genuinely broke.
- check_near_blank - flags latents with variance below
variance_threshold(default 0.0005). A suspiciously flat latent means the sampler produced nothing - the "black image" failure. - check_outlier_saturation - flags latents where more than
outlier_percent_limit% of values sit more thanoutlier_std_thresholdstandard deviations out. This is the "content went off the rails" check.
If every enabled check passes, passed=True and the latent flows through unchanged. If any fails, it returns fallback_latent instead (if connected) and passed=False, with reason telling you exactly which check tripped. Without a fallback connected it returns the original latent anyway - silently handing downstream an empty tensor would break most graphs, which is a design choice worth respecting.
Why median/MAD (the detail that makes this node good)
The outlier check uses median/MAD, not mean/std - deliberately. The pack's changelog is unusually honest about this: an earlier mean/std version failed a constructed test where 20% of a latent's values were extreme outliers, because a large contaminated fraction pulls the mean and standard deviation along with it, hiding the very values that should trip the check. Mean/std have a 0% breakdown point; median/MAD survive up to 50% contamination. In plain terms: the automated gate is engineered not to be fooled by a big bad batch, which is exactly the scenario an overnight run throws at it. Note the pack's Latent Histogram still uses mean/std for its chart stat - different purpose, different statistic, don't expect matching numbers.
Inputs and outputs
- latent - in.
- The three check toggles plus
variance_threshold,outlier_std_threshold,outlier_percent_limit. - fallback_latent (optional) - returned when a check fails.
- latent, passed, reason - out.
The passed boolean is the useful part: wire it into a Conditional Gate to skip the decode/save chain on a failed batch item, or into the pack's Discord Notify to get pinged only when something actually goes wrong - the "wake me if it breaks" pattern.
Install and troubleshooting
No extra dependencies:
cd ComfyUI/custom_nodes
git clone https://github.com/TensorVizion/OmniNodes
Restart, find it under TensorVizion/Latent (ComfyUI Manager, search "OmniNodes", also works).
- Everything fails, all the time. Your thresholds are too tight, or your upstream is genuinely broken. Check
reason- it names the check. Loosenoutlier_std_threshold(default 4) before touching the near-blank variance threshold. - Nothing ever fails. With default thresholds on healthy runs, that's the goal. If you suspect it's not firing, feed it a deliberately corrupted latent (the pack's Latent Noise Inject at high strength is a handy test tool) and confirm it catches it.
- The workflow still saves garbage. The gate only stops what you wire it to stop.
passedis a signal; you have to gate the downstream chain on it.
Set it, connect the fallback, wire passed into your save path, and forget about it. That's the whole point - a node that earns its place by being boring at 3am.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| latent | LATENT | β | |
| check_nan_inf | BOOLEAN | true | β |
| check_near_blank | BOOLEAN | true | β |
| variance_threshold | FLOAT | 0.00050β1 | β |
| check_outlier_saturation | BOOLEAN | true | β |
| outlier_std_threshold | FLOAT | 4.00.5β15 | β |
| outlier_percent_limit | FLOAT | 8.00.1β100 | β |
| fallback_latentopt | LATENT | β |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | β |
| passed | BOOLEAN | β |
| reason | STRING | β |