VAE Latent Inspector
Is your latent NaN-filled garbage? This node tells you before you decode
- latent
- latent_passthrough
- info_json
- verdict
- nan_count
- inf_count
The single most annoying failure mode in ComfyUI is the silent one: you queue a prompt, wait, and get a decode that's black, or static, or a fractal of garbage - with no error, no warning, nothing. Half the time the cause is a latent tensor full of NaN or Inf, and the other half it's a latent with a contrast range so crushed or so blown that the decode is meaningless. VAELatentInspectorMEC is the node that catches both, in one pass, and labels the result with a single word: healthy, low_contrast, saturated, or corrupt.
It's from the ComfyUI-CustomNodePacks pack's diagnostics corner, and it's the kind of node that sounds unnecessary until the first time it saves you twenty minutes of staring at a black image.
How it works
It takes a LATENT tensor (the dict with samples that every sampler outputs), computes per-channel min/max/mean/std, counts NaN and Inf elements, and derives a verdict from the numbers:
healthy- sane range, no NaNs/Infs.low_contrast- values are all squished together; the decode will look flat.saturated- values pinned at the extremes.corrupt- NaN or Inf present. This is the bad one.
The key detail for workflow use: the node passes the latent through unchanged on latent_passthrough, so you can drop it inline into an existing graph - between sampler and decode - and it inspects without disturbing the data flow. No model, no VRAM cost worth mentioning.
Inputs and outputs that matter
latent(LATENT) - the tensor to inspect.fail_on_corrupt(BOOLEAN, default false) - set true and the node raises aValueErroron NaN/Inf instead of just reporting. Use it as a deliberate tripwire in batch runs.
Outputs:
latent_passthrough(LATENT) - the unchanged input, so nothing downstream breaks.info_json(STRING) - shape, dtype, device, per-channel stats, range, verdict.verdict(STRING) - the one-word health label.nan_count,inf_count(INT) - exact counts, so you know how corrupt.
Where it fits
The classic deployment is a batch/pipeline guard: wire it between the sampler and VAE Decode, turn on fail_on_corrupt, and a flaky run fails loudly at the exact node instead of silently producing garbage frames. For debugging a specific broken workflow, it's faster than guessing - the verdict plus the stats tell you whether to blame the sampler (corrupt), the prompt/CFG (saturated), or the denoise settings (low contrast).
Installing it
Standard pack install:
cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks.git
restart ComfyUI or use Manager → "CustomNodePacks". Pure torch tensor inspection - no extra dependencies.
The one thing to remember
NaN/Inf in a latent is almost never the VAE's fault - it's upstream (a sampler step, a broken custom sampler, an out-of-range operation). When the verdict says corrupt, this node tells you that it happened; fixing it means looking at whatever produced the latent. That's a feature: it converts "black image, no idea why" into "the latent is corrupt, and it was corrupt before decode," which is where the real debugging starts.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| latent | LATENT | ComfyUI LATENT dict (must contain 'samples'). | |
| fail_on_corruptopt | BOOLEAN | false | If True, raise ValueError when NaN/Inf detected. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| latent_passthrough | LATENT | Pass-through of the original LATENT input (unchanged). |
| info_json | STRING | JSON with shape, dtype, device, per-channel stats, range, and verdict. |
| verdict | STRING | One-word verdict: healthy / low_contrast / saturated / corrupt. |
| nan_count | INT | Total NaN element count in latent['samples']. |
| inf_count | INT | Total Inf element count in latent['samples']. |