flow_stage_begin
The node that turns one ComfyUI run into a stage-by-stage movie pipeline
- initial_data
- stage_info
- stage_index
flow_stage_begin is where the pack's stage system starts. It's a deceptively small node - three inputs, two outputs - but it's the one that makes a single ComfyUI run process a multi-stage job, checkpointing each stage's data to disk and automatically re-queuing the next one. This is how the pack builds multi-shot videos that are longer than one generation pass: not by loading everything into memory, but by looping.
Think of it as the "for loop header" of a staged workflow. It pairs with flow_stage_end (the loop body's commit point) and flow_stage_unpack (which pulls the previous stage's data back out), plus flow_stage_batch if you want to accumulate per-stage results into one batch.
How it works
The system tracks a "run" - identified by run_id - with a state file and per-stage .safetensors checkpoints stored under ComfyUI/output/.apt_stage_bridge/. On the first stage (current_index = 1), flow_stage_begin creates a fresh run and seeds it with whatever you passed into initial_data. On later stages, it reads the previous stage's checkpoint from disk and hands you the data as stage_info.stage_data, which flow_stage_unpack turns back into image/mask/latent/video/audio.
Because flow_stage_end auto-re-queues the next stage when it saves, the whole thing just keeps running until the last stage sets complete - no manual re-queueing, and a crash mid-way leaves the checkpoint files so you can resume by setting current_index to the breakpoint stage. That resume-from-disk behavior is the part people don't expect from ComfyUI, and it's genuinely handy: kill a 12-stage job at stage 7 and you can restart it at 8 instead of redoing everything.
Inputs
run_id(STRING, default "default") - names the run. Use a distinct id per workflow if you run several staged jobs, or runs will collide.total(INT, default 3) - how many stages the job has.current_index(INT, default 1) - which stage to process, 1..total. Leave it at 1 for a fresh run; set it higher to resume from that stage (the tooltip notes it auto-returns to 1 when the run completes).initial_data(optional, any type) - the seed data for stage 1, usually from an upstream loader.
Outputs: stage_info (FLOW_STAGE_INFO - the handle you pass to every other flow_stage_* node, carrying run id, stage index, total, and stage_data) and stage_index (INT, 1-based, for widgets/prompts that need the current number).
Gotchas
Both flow_stage_begin and flow_stage_end return NaN from IS_CHANGED, which means they always re-execute - that's deliberate (the stage state lives on disk, not in the cache), but it also means everything downstream of the stage nodes reruns every time. Also: total must match what was saved for the run or flow_stage_begin refuses to resume ("total does not match the saved run"). If you change the stage count mid-run, start a fresh run with a new run_id.
Installing it
Ships in cardenluo/ComfyUI-Apt_Preset:
cd ComfyUI/custom_nodes
git clone https://github.com/cardenluo/ComfyUI-Apt_Preset
pip install -r requirements.txt # or double-click install.bat
Restart ComfyUI and you'll find flow_stage_begin under Apt_Preset/flow. No model downloads needed for this node.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| run_id | STRING | default | — |
| total | INT | 31–5000 | — |
| current_index | INT | 11–5000 | 当前阶段(1~总阶段数);可手动选择断点阶段,完成后自动回到1 |
| initial_dataopt | * | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| stage_info | FLOW_STAGE_INFO | — |
| stage_index | INT | — |