Zura · Stage Hand-off
A poor man's context bus that costs you type safety
- previous
- value_0
- value_1
- value_2
- value_3
- value_4
- value_5
- value_6
- value_7
- value_8
- value_9
- value_10
- value_11
- value_12
- value_13
- value_14
- value_15
- value_16
- value_17
- value_18
- value_19
- value_20
- value_21
- value_22
- value_23
- value_24
- value_25
- value_26
- value_27
- value_28
- value_29
- value_30
- value_31
- value_32
- value_33
- value_34
- value_35
- value_36
- value_37
- value_38
- value_39
- value_40
- value_41
- value_42
- value_43
- value_44
- value_45
- value_46
- value_47
- value_48
- value_49
- value_50
- value_51
- value_52
- value_53
- value_54
- value_55
- value_56
- value_57
- value_58
- value_59
- value_60
- value_61
- value_62
- value_63
- stage_data
Zura Studio breaks a project into stages - appearance, motion preparation, sampling, delivery - and the exported Graph view keeps them apart on purpose. Which means stage three needs a value that stage one produced. This node is how it gets there: up to 64 arbitrary named values packed into one wire.
If you've used rgthree's Context, you know the shape. Bundle a handful of connections into one pipe so the graph stops looking like a plate of spaghetti. This is a narrower, stricter version of it, and the strictness is what makes it usable.
Inputs and outputs
keys- a JSON list of signal names as a string, default"[]". Something like["footage", "character_view", "width", "height"].previous(optional) - anotherZURA_STUDIO_SIGNALSbundle. Its contents are copied in first, so the new keys are layered on top. This is how you chain stages without re-passing everything.value_0throughvalue_63- optional*sockets, one per position in yourkeyslist, in order.
Output: stage_data, the ZURA_STUDIO_SIGNALS bundle itself.
Note the * on those value sockets. That's ComfyUI's wildcard type - it'll take an IMAGE, an INT, a string, a model, anything. Which is convenient, and also the reason this node is a debugging hazard: nothing here type-checks what you're carrying, so a footage key that actually holds a width integer won't blow up until three nodes later.
The node validates aggressively on the way in, though. The keys list has to be valid JSON, a list, at most 64 entries, all strings, with no duplicates. And every declared key must actually have its matching value_N connected - miss one and you get "Connect the stage signal: <name>" naming the exact thing you forgot. That's a much better failure than the alternative.
Where it fits
Studio generates these bundles when it exports a stage to Graph view: the stage's upstream objects are packed here, and downstream stage graphs read them back. It's the plumbing that lets you edit one stage's internals without the whole project becoming one unreadable graph.
For hand-built workflows it's also just a neat trick. A closed character-identity set - footage, reference view, resolution, the shot's cache key - travelling on one wire instead of four is the difference between a readable graph and a wall.
Install
Ships with the pack:
cd ComfyUI/custom_nodes && git clone https://github.com/ZURAVFX/ComfyUI_zura_nodes
pip install -r ComfyUI_zura_nodes/requirements.txt
Manager: search Zura Nodes (publisher ZURAVFX) and restart. Nothing extra for this one - it never touches tensors, models or disk. It's pure dict-shuffling.
Common issues
"The stage hand-off contains invalid signal names." keys isn't a JSON list of unique strings. The classic is single quotes from a hand-edit, or trailing commas. It's parsed with a real JSON parser, so ['a','b'] is not valid and ["a","b"] is.
"The previous stage has no signal named …" That error comes from the read node, and it means the key you asked for was never packed upstream. Diff your keys list against the reader's key string. Case matters.
The graph got worse, not better. Almost every time this is the wildcard biting: the pipe swallowed a type error that a plain wire would have caught at connect time. Especially in a workflow you're debugging, prefer direct connections and use the bundle only where the stage really is already shipped that way.
Chained bundles lose things. With previous connected, the new values override same-named old ones and everything else passes through - so a duplicate name isn't an error, it's a silent override. Name things distinctly if a stage re-packs the same concept with a different meaning.
Inputs (66)
| Name | Type | Default | Description |
|---|---|---|---|
| keys | STRING | [] | — |
| previousopt | ZURA_STUDIO_SIGNALS | — | |
| value_0opt | * | — | |
| value_1opt | * | — | |
| value_2opt | * | — | |
| value_3opt | * | — | |
| value_4opt | * | — | |
| value_5opt | * | — | |
| value_6opt | * | — | |
| value_7opt | * | — | |
| value_8opt | * | — | |
| value_9opt | * | — | |
| value_10opt | * | — | |
| value_11opt | * | — | |
| value_12opt | * | — | |
| value_13opt | * | — | |
| value_14opt | * | — | |
| value_15opt | * | — | |
| value_16opt | * | — | |
| value_17opt | * | — | |
| value_18opt | * | — | |
| value_19opt | * | — | |
| value_20opt | * | — | |
| value_21opt | * | — | |
| value_22opt | * | — | |
| value_23opt | * | — | |
| value_24opt | * | — | |
| value_25opt | * | — | |
| value_26opt | * | — | |
| value_27opt | * | — | |
| value_28opt | * | — | |
| value_29opt | * | — | |
| value_30opt | * | — | |
| value_31opt | * | — | |
| value_32opt | * | — | |
| value_33opt | * | — | |
| value_34opt | * | — | |
| value_35opt | * | — | |
| value_36opt | * | — | |
| value_37opt | * | — | |
| value_38opt | * | — | |
| value_39opt | * | — | |
| value_40opt | * | — | |
| value_41opt | * | — | |
| value_42opt | * | — | |
| value_43opt | * | — | |
| value_44opt | * | — | |
| value_45opt | * | — | |
| value_46opt | * | — | |
| value_47opt | * | — | |
| value_48opt | * | — | |
| value_49opt | * | — | |
| value_50opt | * | — | |
| value_51opt | * | — | |
| value_52opt | * | — | |
| value_53opt | * | — | |
| value_54opt | * | — | |
| value_55opt | * | — | |
| value_56opt | * | — | |
| value_57opt | * | — | |
| value_58opt | * | — | |
| value_59opt | * | — | |
| value_60opt | * | — | |
| value_61opt | * | — | |
| value_62opt | * | — | |
| value_63opt | * | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| stage_data | ZURA_STUDIO_SIGNALS | — |