Nodes/ComfyUI-Image-Ledger/Image Ledger · Tracked Image Loader
ComfyUI Node

Image Ledger · Tracked Image Loader

The queue with all the knobs showing

By Rona1do·Created 26 days ago·Updated about 18 hours ago· 1
Image Ledger · Tracked Image Loader
    • image
    • mask
    • job_ticket
    • source_path
    • remaining_pending
    • completed
    • status
    ◄campaignimage-ledger-default►
    ◄source_subfolder►
    ◄recursivefalse►
    ◄selection_moderandom_no_repeat►
    ◄shuffle_seed1337►
    ◄lease_minutes1440►
    ◄auto_queue_nextfalse►
    ◄extensions.png,.jpg,.jpeg,.webp,.bmp,.tif,.tiff,.avif►
    ◄sync_legacy_historytrue►
    ◄legacy_video_glob*.mp4►

    If you're rendering an image library into clips, the moment that hurts is the one where you can't remember which sources you already did. Image Ledger · Tracked Image Loader is the full-fat loader from that pack: it picks an unprocessed source out of ComfyUI/input, reserves it, and marks it complete only when a real video lands. The Visual Queue node is the same engine with five widgets; this one shows you ten, which is the trade you make for control over queue order, reservation timing, and continuous runs.

    What it's for

    Its node description is the summary: selects an unprocessed source image from ComfyUI/input; the image is marked complete only after the final video is saved successfully. That last clause is the reason to use a ledger at all instead of a shell loop - "loaded" and "done" are different states, and only the second one should remove an image from your backlog.

    Take the explicit-node route when you don't want the global panel writing into a LoadImage of its choosing. You wire the source yourself, so there's no guessing which loader in a big graph is the first-frame one.

    How it works

    Four moving parts, in order.

    Indexing. The node walks the source folder, finds files matching your extension list, and computes a SHA-256 for each, caching results so later sessions don't re-hash the world. That hash - not the filename - is a source's identity, which is why a renamed copy still counts as the same image.

    Reserving. reserve_next picks a pending item and marks it running under a token with a lease. Concurrent jobs can't take the same image, and a preview you already looked at gets reused rather than re-drawn.

    Loading. It re-checks the file's size and mtime against what it registered; if the file changed underneath it, it releases the reservation and errors instead of rendering something the ledger can't account for. Then it loads through ComfyUI's own LoadImage via an input-relative path, so junctions and symlinked libraries under input/ work.

    Handing off. It emits a job_ticket JSON blob - token, ledger name, continuous-queue flag - which is what the commit node closes the loop with. sync_legacy_history additionally imports metadata from pre-existing videos in output/video once per session, and stops selection if anything there is unresolved rather than risk a repeat.

    Inputs and outputs

    The ones a beginner actually sets:

    • source_subfolder - e.g. AI for ComfyUI/input/AI; empty scans the input root. The tooltip on recursive is worth heeding: "Disable this when scanning the input root to avoid temporary folders." It defaults off here for that reason, while the simpler node defaults it on.
    • selection_mode - random_no_repeat (the default, a stable shuffle without replacement), or name_asc, name_desc, oldest, newest. Pick a deterministic one when you want a run you can resume predictably by hand.
    • auto_queue_next - off by default, and the tooltip is a precondition rather than a description: "Enable only after confirming that the workflow commits its final video." Turn this on before your commit node is proven and you'll queue your way through a library without anything ever being marked done.

    Then the knobs most people never open: shuffle_seed (default 1337 - change it to re-roll the order without disturbing completion history, since the ranking is derived from ledger name + seed + content hash), lease_minutes (10 to 10080, default 1440) for how long an uncommitted task stays reserved, plus extensions, sync_legacy_history, and legacy_video_glob. campaign is the ledger name - the loaders ship it hidden, and loaders sharing a name share completion history.

    Outputs: image and mask into your sampler chain, job_ticket into the commit node, source_path as a string for filenames, remaining_pending and completed as ints, and status as the familiar Pending 42 | Running 1 | Done 310 | Unique 352 | Duplicates 7.

    Install

    Manager → Custom Nodes Manager → search Image Ledger, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Rona1do/ComfyUI-Image-Ledger.git
    

    Restart ComfyUI. The pack's requirements.txt adds nothing - Pillow, SQLite and aiohttp come from ComfyUI - but the commit half of the loop needs VideoHelperSuite for its VHS_FILENAMES type. Source libraries have to live under ComfyUI/input; a directory link/junction there can point at another drive.

    Common issues

    "No pending images remain in this ledger." Everything's done, or your folder/extension filters match nothing. The message includes the counts, which usually says which.

    "The source image changed after indexing. Run again to refresh its hash." Something rewrote the file - a sync client, an upscaler writing in place. The node released the reservation instead of rendering an unaccounted image; just run again.

    Selection stops with a legacy-import error. sync_legacy_history is on and some old video's metadata couldn't be resolved. Run the Import Video History node with dry_run off to reconcile it, or turn the toggle off.

    It never finishes anything. No commit node, or one missing its job_ticket wire, or a VideoCombine configured to save into temp. Reservations will pile up at Running until their lease expires; the Recovery node clears them.

    CategoryImage Ledger

    Inputs (10)

    NameTypeDefaultDescription
    campaignSTRINGimage-ledger-defaultLoaders with the same name share completion history.
    source_subfolderSTRINGFor example, AI means ComfyUI/input/AI. Leave empty for the input root.
    recursiveBOOLEANfalseDisable this when scanning the input root to avoid temporary folders.
    selection_modeCOMBOrandom_no_repeatrandom_no_repeat is a stable shuffle without replacement.
    shuffle_seedINT13370–2147483647—
    lease_minutesINT144010–10080How long an uncommitted task stays reserved.
    auto_queue_nextBOOLEANfalseEnable only after confirming that the workflow commits its final video.
    extensionsSTRING.png,.jpg,.jpeg,.webp,.bmp,.tif,.tiff,.avif—
    sync_legacy_historyBOOLEANtrueIncrementally imports metadata from existing videos once per session.
    legacy_video_globSTRING*.mp4—

    Outputs (7)

    NameTypeDescription
    imageIMAGE—
    maskMASK—
    job_ticketSTRING—
    source_pathSTRING—
    remaining_pendingINT—
    completedINT—
    statusSTRING—