Jurdns Metadata Image Save
The save node that makes Civitai auto-link your model and LoRAs
- images
- model
- lora_stack
You upload to Civitai, wait for the generation data to populate, and the model and LoRA fields stay stubbornly blank. If you've been saving with ComfyUI's default SaveImage node, that's not you doing something wrong - the default node writes the workflow graph into the PNG but not the flat A1111-style parameters block Civitai's uploader keys on. Jurdns Metadata Image Save is a drop-in replacement that writes that block, model and LoRA hashes included, so Civitai can auto-detect everything. It's the output node in the two-node pack ComfyUI-JurdnsMetadataNodes, and it does exactly one job: save your images as PNGs with Civitai-compatible metadata baked in.
How it works
Under the hood it's a SaveImage that's been taught to speak the right dialect. It builds a metadata string in the A1111 format and stuffs it into the PNG's parameters text chunk:
a cyberpunk street scene at night
Negative prompt: lowres, bad anatomy
Steps: 30, Sampler: dpmpp_2m, CFG scale: 5, Seed: 123456789, Model hash: a1b2c3d4e5, Model: juggernautXL_v9.safetensors, Schedule type: karras, Version: ComfyUI
The interesting part is where the hashes come from. The node traces your model input back to the loader node that produced it, reads the widget holding the filename (that's the model_widget_name input, default ckpt_name - the widget on CheckpointLoaderSimple), finds the file in your checkpoints, diffusion_models, or unet folders, and hashes it. It takes the first 10 hex characters of the SHA256 - the same convention A1111 uses and the one Civitai stores, which is why auto-linking works. The hash is cached to a .sha256 sidecar file next to the model, so it only hashes once; big checkpoints take a couple of seconds the first time and the console prints "Hashing File (SHA256): …".
LoRAs work the same way if you feed the optional lora_stack input - each LoRA gets resolved to its file and hashed, landing in a Lora hashes: "..." line. Heads up: this pack doesn't ship a node that emits LORA_STACK, so you'll grab one from another pack (rgthree and a few others have one).
Inputs that matter
Most of the inputs are forceInput - you can't type into them, you have to wire them. That's deliberate: the settings it records should be the values the graph actually ran, not something you retyped and got wrong. In practice:
images- wire from your VAE Decode.positive_prompt,negative_prompt,sampler_name,scheduler,steps,cfg,seed,denoise- wire these from the pack's other node, Jurdns Prompt Parameters, which exists precisely to hand this node matching values (it emits sampler/scheduler twice: typed for KSampler, strings for here).model+model_widget_name-modelwires from your checkpoint loader; leavemodel_widget_nameasckpt_namefor CheckpointLoaderSimple. If you load via UNETLoader or a Diffusers loader, change it to that node's filename widget (unet_name, etc.) or the trace fails.filename_prefix- the one widget you actually type. Same template language as SaveImage (%date:yyyy-MM-dd%, subfolders with a/).lora_stack(optional) - for LoRA hashes.
It has no outputs and is an output node, so drop it last in the graph; files land in ComfyUI/output/ like any SaveImage.
Install
It's a two-node pack with zero dependencies - no requirements.txt, no model downloads, just Python on ComfyUI's own libraries. Easiest path is ComfyUI Manager → Install Custom Nodes → search "ComfyUI-JurdnsMetadataNodes", then restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/jurdnf/ComfyUI-JurdnsMetadataNodes
Restart ComfyUI and both nodes appear under the "Jurdns" menu.
Where people get burned
Model hash: unknown_hashin the saved PNG. Themodel_widget_namedoesn't match the loader's actual widget, or the model file isn't in a folder the node checks. Fix the widget name.- Hash present, but Civitai still won't link the model. The hash is of your local file, and Civitai matches exact hashes. Renamed, repacked, or fp16-converted checkpoints hash differently than the original upload, so they won't match the listing - the same limitation A1111 always had. Nothing the node can do about it; it's a property of the hash convention.
- Metadata vanishes when you share. Anything that re-encodes the image - Reddit's image hosts, screenshots, JPEG export - strips the
parameterschunk. Post the original PNG. - Seed lies. If KSampler randomizes its seed internally, the seed you wired in here is what gets recorded, not what KSampler actually used. Keep one source of truth for the seed and feed it to both.
One last tell about the project's scale: the pyproject.toml still names the pack "ComfyUI-JurdnsIterativeNoiseKsampler" - a copy-paste from the author's other project. Cosmetic and harmless, but it tells you this is a small single-author utility, not some maintained ecosystem heavyweight. It does its one job fine.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| filename_prefix | STRING | ComfyUI | — |
| model | MODEL | — | |
| model_widget_name | STRING | ckpt_name | — |
| positive_prompt | STRING | — | |
| negative_prompt | STRING | — | |
| sampler_name | STRING | — | |
| scheduler | STRING | — | |
| steps | INT | — | |
| cfg | FLOAT | — | |
| seed | INT | — | |
| denoise | FLOAT | — | |
| lora_stackopt | LORA_STACK | — |
Outputs (0)
No outputs