Smart Debug Node
Actually see what's flowing through your ComfyUI workflow
- data
- data
ComfyUI hides everything between the model load and the image you finally see. You know the drill: something comes out wrong, you've got a hunch it's the latent or the conditioning or that one tensor, and your only tool is staring at a black box and re-rolling the seed. The Smart Debug Node (class DebugPrintNode, part of the ComfyUI-Doctor pack) is the tool for that moment. You drop it inline, run the workflow, and it dumps a readable inspection of whatever passes through it - then hands the data along untouched, so your output is exactly what it would have been.
It's not glamorous, and it's not the flashiest thing Doctor ships. It's the boring node you'll reach for constantly once you know it exists.
What it does
Everything about this node is "inspect, don't touch." It takes a single data input of type * - literally any type, images, latents, conditioning, models, strings, lists - plus an optional prefix string (default DEBUG) that labels the output so you can tell one print apart from the other when you've got a few in a chain.
Under the hood it walks the data structure recursively (to a max depth of three, so it won't hang on something pathological) and prints what it finds:
- Tensors get the useful stuff: shape, dtype, device, plus a min/max/mean over the values. It also flags two genuinely critical states -
NaNandInf- and warns on meta tensors andrequires_grad=True. - Dicts are checked for a
sampleskey, which is how it recognizes aLATENTand digs into it (also checking fornoise_maskandbatch_index). - Lists get a peek at the first item, and it recognizes the
[[Tensor, Dict], ...]shape ofCONDITIONINGand says so. - Models and objects report what attributes they actually have -
model_type,load_device,dtype. - Everything else just prints its value, truncated to 200 chars.
The node returns the exact data it received, so you can splice it into any connection without worrying it changes the math. It is a true pass-through, not a "mostly pass-through."
The part the README underplays
The print goes to console output - and ComfyUI-Doctor's whole premise is that it captures console output from startup. That's the synergy. In a bare ComfyUI install, a print node's output lands in a terminal you probably aren't watching. With Doctor installed, that same [DEBUG] block shows up in the Doctor sidebar, searchable alongside your error history. If the values look wrong, you've got the workflow in front of you and a debugging context to talk about it with.
This is where the community's debugging principle comes in: lock the seed and change one thing at a time. The Smart Debug Node is how you see the one thing. That NaN check in particular matters - NaN propagation is a classic ComfyUI failure mode (older GPUs choking on fp16, xformers version mismatches) and catching it at the node that produces it beats staring at a black decode later.
Installing it
The node ships inside ComfyUI-Doctor, so you install the pack, not the node:
- ComfyUI Manager: open Manager → Install Custom Nodes → search
ComfyUI-Doctor→ install and restart. - Manual:
cd ComfyUI/custom_nodes && git clone https://github.com/rookiestar28/ComfyUI-Doctor.git, then restart ComfyUI.
One genuinely nice thing: pyproject.toml declares zero runtime dependencies. No torch pin, no extra pip installs - it runs on ComfyUI's bundled environment plus the standard library. That's rare in this ecosystem and means installs basically can't break your other nodes.
Once it's in, right-click the canvas, search "Smart Debug Node," and wire it between the node you suspect and wherever its output goes.
Gotchas
The inspection has its limits, and knowing them saves you a false alarm. List items beyond the first are hidden (... (hidden N items)), dicts stop after the first few keys, and depth caps at three - so huge batches and deeply nested structures only get summarized, not fully printed. Stats are computed over the full tensor when small or a 10k-element sample when large, which is a deliberate speed trade-off. And the data output is typed *, so if you rely on strict output types for downstream nodes you may need to be mindful of what type checker you're running. For a debug node, that's a fair price for "accepts everything."
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| data | * | — | |
| prefix | STRING | DEBUG | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| data | * | — |