- image
- IMAGE
You know the moment: you're testing two samplers, so you bypass one, hit Queue, and your Preview node suddenly shows nothing - because bypassing a node physically removes its output from the graph, and everything wired after it just gets air. Image Hold Last exists to make that moment not happen. It's a passthrough that caches the last image it saw and replays it whenever its input goes quiet.
The name is the whole pitch. There's no API, no key, no config, nothing hidden. You drop it into a wire, and if the upstream node is bypassed, muted, or otherwise not delivering, the downstream nodes keep getting the last good image instead of an empty socket.
How it holds the image
Under the hood it's about fifteen lines of Python in one file. The hold function has three states:
- Image connected and flowing → it stores a copy and passes it through.
- Input missing (upstream bypassed/muted) → it returns whatever it stored last.
- Nothing ever arrived → it returns a 1×1 black pixel (
torch.zeros(1, 1, 1, 3)) so the pipeline stays alive rather than erroring.
The trick that makes this work is IS_CHANGED returning time.time(). ComfyUI caches aggressively, and a passthrough with an unchanged input would normally be skipped on re-runs - which would mean it never gets a chance to notice a new image. By claiming "I changed" every single time, the node forces itself to run on every queue execution, exactly like the always-rerun nodes covered in the plumbing docs. Cheap and effective, but it means the node never sits in the cache - harmless here since its only job is to hold one tensor.
One thing to internalize: the cache lives in memory on the node object, not on disk. Restart ComfyUI, or delete and re-add the node, and it forgets everything - you're back to the 1×1 black pixel until an image flows through once. The "hold" is for bypassing mid-session, not for persistence.
The input and output (that's all there is)
image(IMAGE, optional) - wire any IMAGE output into this. Optional, so an unwired input is perfectly legal; it just means the node has nothing to hold.- Output:
IMAGE- goes straight into whatever the bypassed node used to feed: Preview, Save, VAE, controlnets, you name it.
No widgets, no required inputs, no settings. If you've used any ComfyUI node ever, you know how to use this one.
Installing it
Via ComfyUI Manager, search Image Hold Last and install. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/SeBL4RD/Image-Hold_Last
Then restart ComfyUI. It's in the utils category. There are zero dependencies and no model files - the pyproject.toml declares an empty dependency list, so it can't break your install. One small trap: the pack's own README shows a different clone URL (comfyui-image-hold-last) that doesn't resolve. Use the command above.
Using it without shooting yourself in the foot
The intended pattern is the conditional-bypass branch: sampler → this node → Preview, then bypass the sampler when you want to keep the last output. It also works as a janky-but-free "last good frame" holder if you're muting a loader.
Two gotchas are worth knowing before you trust it:
- The README warns that multiple instances in one workflow share a single cache, with the last one to receive overwriting the rest. The shipped code doesn't actually do that in current ComfyUI - the held image is stored on the node instance, and ComfyUI gives each node its own instance. Each one holds its own image. That's good news, but treat the README as a warning to verify on your own version rather than gospel.
- The no-data fallback is a single black pixel. If you look at your Preview and see a tiny black dot, that's not a broken node - it means nothing ever reached it. It keeps the graph running, but it isn't art.
Should you bother? It's one of those 15-line nodes that feels too small to matter until you need it. If you want something with a bit more spine - a real first-non-null switch you can flip between several branches - you'd reach for a fallback switch like rgthree's Any Switch instead. But when all you want is "bypass this, keep the image," this is the simplest thing that works, and simple is worth a lot in a 200-node workflow.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| imageopt | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |