♾️ Save Any
One node that saves images, masks, latents, audio, and text
- input
- mask
Every loop needs a write side, and in ComfyUI-Loop that's Save Any (SaveAny). It takes any of the pack's supported inputs - image, mask, latent, audio, text - and writes it to a file you point at. On its own that sounds like the most boring node imaginable. In context, it's the thing that makes the whole "loop" idea real: Loop Any loads a file, your pipeline improves it, Save Any overwrites that same file, and the next run starts from the improvement instead of from scratch. The README's framing is exactly right - this is a "save by overwriting" node built for iterative inpainting.
How it works
Save Any pattern-matches the input tensor, the same way its partner Loop Any does:
- 4D image tensor →
.png(and if you pass amaskinput, it's written into the PNG's alpha channel) - 3D tensor (a mask) →
.png - a latent dict →
.latent - a
{waveform, sample_rate}dict →.flac str/int/float→.txt
The path input is a full file path with extension - that's how it knows the format, and it's why Loop Any hands you a ready-made path output to feed straight in. If the input type doesn't match the extension you typed, the format wins and the file just gets whatever extension the type implies.
The inputs that matter
input- anything the pack understands.path- full path of the saved file (default/path/to/file.ext). Set this yourself, or wire it from Loop Any'spathoutput so the loop closes.save_steps- saves a timestamped copy next to the main file on every run. This is the one I'd switch on first: in a loop that overwrites on each pass, it's your only history. Turn it on, and you can scroll through the progression afterward instead of wondering what pass three looked like.save_metadata- embeds prompt/graph metadata into formats that support it (PNG). Nice-to-have for sharing; leave off if you're just iterating.preview- shows the image preview in the node. Disable to shave a hair off execution and de-clutter big graphs.mask(optional) - the inpainting linchpin: with an image input, this mask gets saved as the PNG alpha channel. Loop Any withloop_maskon reads it back, so a single file carries both the inpainted region and its mask.
It's a terminal node - no outputs, just the on-node preview.
Why you'd reach for it
Because the default SaveImage node fights you on loops. It auto-numbers every file, so re-runs pile up and "load the previous result" has no fixed target. Save Any gives you a deterministic file: same path, overwritten every run. That determinism is what Loop Any needs to load the last iteration back. The mask-as-alpha trick is the real gem though - it's the cleanest way to keep an inpainting mask in lockstep with the image through a feedback loop, no separate mask file to drift out of sync.
Install and gotchas
No dependencies, no models - the whole pack installs the same way:
cd ComfyUI/custom_nodes
git clone https://github.com/Hullabalo/ComfyUI-Loop
Restart, done. Manager users: search "Loop" for ComfyUI-Loop.
- It overwrites silently. That's the design, but the README's warning is mandatory reading: always work on a copy of your source file. With
save_stepsoff, there's no undo. - No batch or list support - single files only, pack-wide limitation.
- Not Nodes 2.0 compatible. Tested through ComfyUI 0.8.2 on the legacy frontend; the new Vue canvas breaks it, and the author has said it likely never gets ported.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| input | * | — | |
| path | STRING | /path/to/file.ext | Full path of the saved file. |
| save_steps | BOOLEAN | false | Save a copy next to the saved image with a timestamp as suffix. |
| save_metadata | BOOLEAN | false | Save metadatas for compatible file formats. |
| preview | BOOLEAN | true | Display the preview in node. |
| maskopt | MASK | — |
Outputs (0)
No outputs