Nodes/ComfyUI Local Run Receipts/Local Run Receipts: Build Run Key
ComfyUI Node

Local Run Receipts: Build Run Key

A Stable ID for Every ComfyUI Run (Built From What You Declare)

By nawnie·Created 2 months ago·Updated 2 months ago· 0
Local Run Receipts: Build Run Key
    • run_key
    • canonical_record
    namespacelocal
    labelSD 1.5 image
    seed0
    parameters_json{"sampler":"euler","steps":20}
    parent_run_key

    Give every run a name it can't forget

    Local Run Receipts: Build Run Key is the front half of a two-node pair, and it does exactly one job: it turns values you type into a stable identifier for a run - a canonical JSON record plus a key like lrr1_3f9a... (a SHA-256 hash of that record). No models get loaded, no files get written, nothing gets uploaded. It builds a key; its partner node, Commit Image Run, is the one that actually saves your images under it.

    Why bother? Without a stable key, "did I already run this?" is a guess. With one, the commit node can give you a definitive answer: CREATED if this is new, ALREADY_IDENTICAL if the same declared values already produced these exact pixels, or a hard stop if the same key somehow produced different pixels. That turns retries and parameter sweeps from a trust-me exercise into something the workflow itself can verify.

    How it works

    The node normalizes your declared values (trims and length-checks text, requires a non-negative integer seed), canonicalizes them into JSON with sorted keys and no whitespace, and hashes it. Deterministic: same declared values in, same lrr1_ key out, every time, on any machine. That's what makes the key worth anything - a fingerprint of the run as you described it.

    The catch, and it's a real one, is the phrase "as you described it." The node never inspects your model weights, sampler, LoRAs, or CUDA kernels - it hashes exactly what you type in and nothing more. Two runs that declare identical values but use different models will share a key, and the commit node will flag byte-different images as a conflict instead of starting a fresh run. So this key detects changed runs and accidental retries; it's not a claim of bit-for-bit reproducibility. The README is blunt about this: it does not prove the same weights, custom nodes, or machine settings were used later.

    The inputs that matter

    • namespace (default local) - your scope. Think of it as a tenant or project name; use something more specific than local once you have more than one experiment going, or all your runs compete for the same bucket.
    • label (default SD 1.5 image) - a human-readable description of the run. Cosmetic, but it lands in the receipt and makes a folder tree legible later.
    • seed - the seed you intend to use. It's just a declared integer up to 2^53−1 (the largest integer ComfyUI's frontend handles cleanly); the node doesn't verify the sampler actually used it.
    • parameters_json (default {"sampler":"euler","steps":20}) - the real payload. This must be a valid JSON object. Declare whatever makes a run distinct here: sampler, steps, CFG, model name, resolution. This is the field that actually differentiates runs.
    • parent_run_key (default empty) - optional chaining. Feed it a valid lrr1_ key to mark this run as a child or retry of an earlier one; it gets recorded in the receipt.

    Outputs: run_key (the lrr1_... string) and canonical_record (the normalized JSON). Wire both into Commit Image Run - the commit node re-derives the expected hash from the record and errors if it doesn't match the key, so you can't silently mix records.

    Install

    The pack is new and the Registry listing is pending, so until it's live, clone and restart:

    cd ComfyUI/custom_nodes
    git clone https://github.com/nawnie/ComfyUI-Local-Run-Receipts
    

    Restart ComfyUI after. Once the listing publishes you can install "Local Run Receipts" from ComfyUI Manager instead. There are no models to download and no dependencies beyond Pillow and NumPy (already part of ComfyUI), though it needs ComfyUI 0.28.0+.

    Troubleshooting

    • parameters_json must be valid JSON - the most common beginner trip. Paste a prompt instead of an object, or leave a trailing comma, and you get a clean error before anything runs. It must parse to a JSON object specifically, not a list or a number.
    • Same key, different images, conflict error - you forgot to declare something that actually changed (a model, a LoRA, a step count). The fix is to add it to parameters_json or bump the seed so the run gets its own identity.
    • A quick smoke test - the pack ships a no-model starter that makes a 128px empty image and commits it with a receipt, no GPU involved. Run it twice to see CREATED then ALREADY_IDENTICAL, and change a declared value to watch the key change. It talks only to 127.0.0.1:8188 by default (--port if yours is elsewhere).

    Use this node the way you'd use a commit hash: as an identity for the values you decided to save, declared honestly and checked automatically. It won't do the honesty part for you.

    Categoryoutput/local run receipts

    Inputs (5)

    NameTypeDefaultDescription
    namespaceSTRINGlocal
    labelSTRINGSD 1.5 image
    seedINT00–9007199254740991
    parameters_jsonSTRING{"sampler":"euler","steps":20}
    parent_run_keySTRING

    Outputs (2)

    NameTypeDescription
    run_keySTRING
    canonical_recordSTRING