Nodes/comfyui-exr-plate/Path Builder (versioned)
ComfyUI Node

Path Builder (versioned)

Stop overwriting v003 with v003

By Samuelsujan·Created 4 days ago·Updated 4 days ago· 7
Path Builder (versioned)
    • path
    • folder
    • version
    folder
    nameplate
    version_mode
    version1
    version_pad3
    version_style
    frame_token
    ext
    create_dirsfalse
    subpath

    Rendering a plate you like and then rendering six more variants into the same filenames is a rite of passage, and it's the reason this node exists. It has no pixels in it at all: you show it a folder, give it a name, and it hands out a versioned output path - .../v003/plate.####.exr or .../plate_v003.####.exr - bumping the version at execute time so queueing twice writes v004 and then v005 instead of quietly eating your last render.

    It's the third node in Samuelsujan's EXR Plate pack, and it assumes you live in a show folder. Most path nodes in the wild are show + shot + task + version text fields you paste absolute paths into, which is how a full path ends up in the shot box and the render ends up on your desktop. This one is deliberately dumber: one browsed folder, an optional subpath, a name. That's the author's framing and it's the right call.

    How it works

    There's a Browse button in the node that opens a server-side file dialog - the /exrplate/browse endpoint lists directories on the machine running ComfyUI, with drive letters on Windows, a .. to walk up, and up to 60 files listed for orientation. It walks the filesystem; it does not type paths for you.

    The version resolution happens when the graph executes, not when you set the widget, and the rule is a small regex over what's on disk (v003, _v012, plate.v7 match; rev2 and version_2 don't). Which names get scanned depends on version_style:

    • folder - looks at subdirectory names under the base folder.
    • filename - looks at files whose names start with name.

    Then version_mode decides what to do with the highest number found: auto_next = highest + 1 (writing a new version), auto_latest = highest (reading the current one), manual = whatever the version widget says. Scanning is padding-agnostic - v3 and v003 both count, and the highest number wins - so changing version_pad won't orphan older versions.

    The always-bump behaviour is a specific, well-known ComfyUI trick rather than a hack: in the two auto modes the node's IS_CHANGED returns float("NaN"), and because NaN isn't equal to anything - including another NaN - ComfyUI can never cache-match it, so the node re-executes on every queue. In manual mode it returns a normal hash string and caches again. Once resolved, the node pushes the result back to the UI over a socket, which is what keeps the "next run writes this" readout on the node honest instead of just echoing your widgets.

    Inputs, outputs, and what wires where

    You'll set four things in practice: folder (Browse, don't type), name (the filename stem - END_130_comp, not a path), version_mode, and version_style. Everything else is a formatting preference:

    • frame_token - ####, ########, %04d, %08d, or none for a single file.
    • ext - exr/tif/png/jpg, for the path string only. Save Plate always takes the extension from its own format dropdown, so this matters for Load and for reading the path, not for what gets written.
    • version_pad (default 3, so v003), version (only read in manual), create_dirs (off by default - Save creates the folder anyway; flip it on if a Load node needs the folder to exist first), subpath (optional folder(s) under the browsed one, e.g. comp/renders).

    Three outputs, all worth knowing:

    • path - wire it into Save Plate's path (right-click the widget → Convert widget to input) or into Load EXR Plate's path.
    • folder - the resolved version directory. Handy for the load side, or for anything else that needs the folder rather than the file.
    • version - an INT. In auto_latest it's floored at 1, so it never returns 0.

    The slick two-node pattern: one builder in auto_next → Save, and a second builder pointed at the same base folder in auto_latest + version_style: folder + frame_token: none → Load. Now the load branch is always reading whatever version you last wrote, and nothing in the graph has a hardcoded version in it.

    Installing it

    Same pack, same one-time setup - ComfyUI Manager → search EXR Plate (Samuelsujan's EXR Plate) → Install, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Samuelsujan/comfyui-exr-plate
    python -m pip install -r comfyui-exr-plate/requirements.txt   # opencv-python>=4.6, numpy
    

    Restart, then hard-refresh the browser (Ctrl+Shift+R). The Browse dialog and the live readout are JS from the pack's web/ folder - without a refresh you get a dead button and no version display.

    Where people get burned

    • folder style ignores name when scanning. It scans every subdirectory for a v### and takes the highest, so if multiple shots share one output folder, your version numbers jump based on a sibling's folders. One shot per base folder, or use filename style.
    • auto_latest on an empty folder resolves to 1 and hands you a path to a version that doesn't exist yet - so a Load wired from it errors. Expected, but it looks like a bug the first time.
    • Version doesn't bump. Check version_mode isn't on manual (that's the caching path), and that existing folders really match v###. rev2, version_2 and V3_final are invisible to the scan and get skipped.
    • Browse shows the wrong computer. The dialog runs server-side, so on a remote ComfyUI host you're browsing that machine's disks. On a hosted ComfyUI there are no custom nodes at all.
    • A version in the name. Keep it to a stem; hand-typing plate_v003 gets you plate_v003_v004.
    CategoryEXR Plate

    Inputs (10)

    NameTypeDefaultDescription
    folderSTRINGBase folder. Use the Browse button — it walks the machine ComfyUI is running on.
    nameSTRINGplateFilename stem, e.g. END_130_comp
    version_modeCOMBOauto_next = highest on disk + 1 (write). auto_latest = highest on disk (read). manual = use the version widget.
    versionINT10–9999Only used when version_mode is manual.
    version_padINT31–6
    version_styleCOMBOfolder -> .../v003/plate.####.exr filename -> .../plate_v003.####.exr
    frame_tokenCOMBOSequence padding. 'none' for a single file.
    extCOMBOSave Plate overrides this from its own format dropdown; it matters for Load and for reading the path.
    create_dirsBOOLEANfalseMake the folder now. Save Plate creates it anyway — turn this on if a Load node or another tool needs it to exist first.
    subpathoptSTRINGOptional folder(s) under the browsed one, e.g. comp/renders

    Outputs (3)

    NameTypeDescription
    pathSTRING
    folderSTRING
    versionINT