Mememage Save Record
Save the record (and a metadata-free PNG) that goes with your image
- image
Here's the thing about Mememage Encode: it only returns the record. Nothing stores it. Mememage Save Record is the node that actually writes the record .json to disk - and, if you wire the image in too, the barred image as a lossless PNG. It's the output node at the end of the pipeline, the "save" button for the whole provenance system.
The mental model that makes the filenames make sense
Most image+sidecar systems glue the two files together by name. This one deliberately doesn't. The README's line is worth keeping in your head: the bar links image to record, not the name. The identifier and content hash live in the pixels, so the .png and the .json never need to share a filename - they're reunited by math, not by naming convention. That's why the default filenames (both just the record's <identifier>) feel oddly bare. They're the one default that lets Mememage Find Record locate the record by identifier with no path, and they give a tidy pair that overwrites in place as you iterate a pinned piece.
Inputs
record- wire Encode'srecordoutput here. Required in spirit; the node no-ops cleanly if you wire nothing.image- optional, but this is the one to know about. Wire Encode'simageoutput here and it writes the barred PNG as lossless.png. The image is optional because any saver works - the bar carries identity, not the file. But there's a reason to prefer this path (see below).record_name/image_name- free-form. Blank = the<identifier>. A bare stem gets.json/.pngappended; a name with its own extension is used as-is. Override freely, but know that when a name isn't the identifier, you'll discover/verify the record by path rather than by identifier.subfolder- a subfolder under ComfyUI's output directory.
The privacy-safe save path
This is the node's quiet superpower, and it's a direct answer to a real ComfyUI footgun (documented at length in our image-io-metadata KB): stock SaveImage bakes the entire workflow graph into every PNG as text chunks - including the plaintext of anything typed into node widgets. Mememage's own encryption seals the record's fields, but it can't reach ComfyUI's PNG metadata. The two savers, two outcomes:
- Mememage Save Record writes the PNG with no metadata at all - clean.
- Stock SaveImage bakes the graph, so a widget-entered secret sits in the file in the clear.
So if you're stamping anything private, saving through this node (instead of stock SaveImage) is the single simplest fix. Scope note: the exposure is the local file at rest - re-encoded copies (Discord, Instagram, JPEG conversion) strip the chunks anyway. What carries them is the raw file: an email attachment, a "send as file," a cloud-synced folder. Whether that matters is your call, but now it's an informed one.
Installing it
Standard for the pack. ComfyUI Manager → search "Mememage" → Install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/sememtac/mememage-comfy
<ComfyUI-python> -m pip install mememage
Restart; it's under Mememage/Records. No model downloads, no keys.
Common issues
- "It said nothing saved." The node's UI text reports
nothing saved - not a valid recordwhen the record input is blank or not parseable (e.g. an empty placeholder from a switch). Wire a real record. - "My custom-named record won't verify by identifier." Right - a custom name means the by-identifier fast path misses. Load it by path (Mememage Load Record) or use Find Record, which scans by content and is name-blind.
- "Earlier renders of my pinned piece fail to verify." That's the pinned-identifier contract, not a filename bug - the record only holds the latest hash. Keep a numbered Save Image if you want a history.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| imageopt | IMAGE | Wire Encode's `image` output here to also save the barred image (lossless PNG). Optional — any saver works; the bar, not the file, carries identity. | |
| recordopt | STRING | Wire Encode's `record` output here — the record to save. | |
| subfolderopt | STRING | Optional subfolder under the output directory. | |
| record_nameopt | STRING | Filename for the record. Blank = the record's <identifier> (keeps Load-Record-by-identifier working). `.json` added if you omit it. | |
| image_nameopt | STRING | Filename for the image (only if wired). Blank = the <identifier>. Free to differ from the record. `.png` added if you omit it. |
Outputs (0)
No outputs