Nodes/ComfyUI-Apt_Preset/flow_stage_end
ComfyUI Node

flow_stage_end

The node that saves a stage and queues the next one for you

By cardenluo·Created 2 years ago·Updated a day ago· 320
flow_stage_end
  • stage_info
  • data
  • list_data
data_typeauto
unload_modelsfalse
free_memorytrue

flow_stage_end is the commit point of the pack's stage-loop system - the counterpart to flow_stage_begin. Its job: take whatever your stage produced, serialize it to disk as a numbered checkpoint, and then automatically add the next stage to the queue. You hit Run once, and the workflow re-runs itself stage by stage until it's done. It's the closest thing ComfyUI has to a built-in "generate this whole storyboard" button.

It's marked as an output node, so it always runs, and its IS_CHANGED returns NaN - meaning it re-executes every pass regardless of caching, which is exactly what you want for something whose state lives on disk.

Inputs

  • stage_info (FLOW_STAGE_INFO) - from flow_stage_begin. It tells the node which run and which stage it's committing, and it validates the order (a stage that isn't next gets rejected rather than silently corrupting the run).
  • data (any type) - the stage's result: an image, mask, latent, video, audio, tensor, or JSON. Type is auto-detected.
  • data_type (default "auto") - lets you force the type if auto-detection ever guesses wrong. Options: auto, latent, image, mask, video, audio, tensor, json.
  • unload_models (BOOLEAN, default false) - sets ComfyUI's "unload models" flag for the next pass. Useful if a stage doesn't need the diffusion model and you want VRAM freed.
  • free_memory (BOOLEAN, default true) - same idea for memory cleanup between stages.

Output: list_data - a list of all stage payloads, but only on the final stage (it's an ExecutionBlocker(None) placeholder otherwise). That's the trick: you can wire it to a Save node or a preview and it only produces real data once the whole run is complete.

How the loop actually works

On every stage, flow_stage_end writes stage_{n:05d}.safetensors plus a state.json into the run's folder under ComfyUI/output/.apt_stage_bridge/, using an atomic temp-file-then-rename so a crash can't leave a half-written checkpoint. If the stage isn't the last one, it tells the server to add another queue entry - that's the auto-re-queue. On the final stage it flips the state to complete, collects all the stage files into list_data, and the loop stops. The begin node's current_index widget even updates live as stages progress, and resets to 1 when done.

Where people get burned

The "active run already exists" error is the classic: if the state file says a run is mid-flight and you queue a stage 1 for the same run_id again, it refuses. That's a safety valve - either let the run finish, delete the run folder under .apt_stage_bridge, or use a fresh run_id. And because the loop is auto-re-queued, a bug that fails before flow_stage_end runs means the workflow just stops (no checkpoint for that stage) rather than looping forever - which is the right failure mode, but worth knowing when you're debugging.

Installing it

Part of cardenluo/ComfyUI-Apt_Preset:

cd ComfyUI/custom_nodes
git clone https://github.com/cardenluo/ComfyUI-Apt_Preset
pip install -r requirements.txt   # or install.bat on Windows

Restart ComfyUI; it appears under Apt_Preset/flow. No models to download for this one.

CategoryApt_Preset/flow

Inputs (5)

NameTypeDefaultDescription
stage_infoFLOW_STAGE_INFO
data*
data_typeCOMBOauto8 options: auto, latent, image, mask, video, audio, +2
unload_modelsBOOLEANfalse
free_memoryBOOLEANtrue

Outputs (1)

NameTypeDescription
list_data*