Zura · Load H3 Continuation
Reading back the previous window, with proof it's the right one
- continuation_state
- guide_frames
Loading saved state in a graph is normally a one-line affair. This one is forty lines of validation, and once you've been bitten by a stale continuation you'll be glad it is. MiniMax H3 renders in 124-frame windows locally - roughly five seconds at 24 fps, versus the up-to-15-seconds the model advertises through the API - so long takes are chains of windows, and every link in that chain has to be provably the right one.
What it loads and from where
The save node writes into your ComfyUI output directory, under genj/h3_continuation/<generation_digest>/window-NNNNNN/. Each window directory holds two files: state.json, a small manifest envelope, and state.safetensors, carrying exactly two tensors - the two-token video prefix and the five-frame guide image.
This node takes a window index, subtracts one, and loads only that adjacent predecessor. There's no "load any window you like"; the state directory is derived from next_window_json and the digests, and the containment check insists the resolved path stays inside the output folder.
Why the validation is the feature
Before it hands you anything, it checks:
- the manifest schema, context frame count and prefix length,
- the SHA-256 of
state.safetensorsagainst the digest recorded in the envelope, - the safetensors metadata manifest against the manifest file, byte for byte,
- both tensor hashes, shapes and dtypes - prefix
[1, 24, 2, H/16, W/16], guide[5, H, W, 3], - that the previous window is genuinely adjacent, in the same shot, with the right owned-end/owned-start relationship and the five-frame overlap the H3 prefix contract requires.
Then it compares generation digest, model digest and raster against what you passed in. Change the seed, swap the model, or nudge resolution between windows and you get "The H3 continuation belongs to a different generation, raster, window or shot." That error is the node working, not failing - the alternative is a window that samples a prefix from a different render and a seam nobody can explain.
It also refuses symlinked or junction-redirected store directories, which is a small but real hygiene check: output/genj/h3_continuation must be a real folder inside ComfyUI's output.
One behavioural quirk: IS_CHANGED returns NaN, ComfyUI's cache-bypass idiom. That forces this node to re-validate the file on disk on every run, even when the prompt is byte-identical. Correct for a loader whose inputs can change without the graph changing - and it means this branch always re-executes.
Inputs and outputs
next_window_json-STRING, the planner's record for the window you're about to render.generation_digest,model_digest-STRING, lowercase SHA-256 digests. Must match what the save node used.width,height-INT, defaults 704 × 1280, multiples of 32. The generation raster - checked against the state.continuation_state-H3_CONTINUATION, into Zura · Apply H3 Continuation.guide_frames-IMAGE, the predecessor's real tail frames, into the native guide node at frame 0.
Install
cd ComfyUI/custom_nodes && git clone https://github.com/ZURAVFX/ComfyUI_zura_nodes
pip install -r ComfyUI_zura_nodes/requirements.txt
Restart. safetensors comes with ComfyUI; the H3 weights are the separate, territory-licensed downloads. Note the store lives in your output folder - clearing ComfyUI's output is the fastest way to break a long render's chain, and there's no recovery except starting from window 1.
Common issues
"The saved H3 continuation is missing, stale, corrupt or mismatched." One deliberately opaque error for a dozen cases. Most often: you cleared the output folder, you changed the seed/model/resolution, or you're running window N+1 in a fresh ComfyUI session against a store built with different digests.
"This H3 window has no valid same-shot continuation predecessor." You asked for window 0, or the window you're loading sits right after a cut. Cut-reset windows start unconditioned by design.
"The H3 generation width and height must be multiples of 32." The raster check is exact, because the prefix tensor's shape depends on it. 704 × 1280 are the tested defaults - if you're experimenting with odd sizes, keep them on the 32 grid.
It runs every time you hit Run, even with nothing changed. That's the NaN. Intentional, and cheap - it's a file read and a hash.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| next_window_json | STRING | {} | — |
| generation_digest | STRING | — | |
| model_digest | STRING | — | |
| width | INT | 70432–8192 | — |
| height | INT | 128032–8192 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| continuation_state | H3_CONTINUATION | — |
| guide_frames | IMAGE | — |