Unpack
Pull your MODEL, CLIP, VAE and friends back out of a Pack
- PACK
- value_1
ComfyUI's socket types are strict - a MODEL socket only takes a model, a CLIP only a CLIP - and that strictness is usually the thing keeping your graph honest. It's also the thing that makes bundling awkward: sometimes you just want to move a whole pile of different-typed values through one connection, and the type system fights you. Unpack is the receiving end of the pack's answer to that: bundle anything into a Pack, run it across your graph, then Unpack restores every value as its original, properly-typed socket.
Think of Pack/Unpack as a labeled courier. One Pack can carry a MODEL, CLIP, VAE, CONDITIONING, and IMAGE at once - types that can't normally share a socket - and Unpack hands each one back in its own lane, name and type intact.
How it works
Pack doesn't just stuff values into a tuple. When it runs, it inspects the workflow graph (via the unique_id, prompt, and extra_pnginfo it pulls as hidden inputs) and records each input's name, type, and value into a PACK dict. Unpack receives that dict, reads the stored metadata, and returns the values - while the frontend rebuilds its output sockets to match, using a bypass-type mechanism that swaps the generic sockets for the Pack's real types.
The neat part: Unpack doesn't have to be bolted directly onto Pack. Its JS traces the upstream connection, and per the README it can even follow through some intermediate nodes - switch-style or Anything-Everywhere-style nodes - as long as the originating Pack is discoverable. That's what makes it genuinely useful in big graphs: you can route a whole bundle through a switcher and unpack it near the sampler.
The input and outputs
- PACK - connect the PACK socket from a
Packnode (or a traced intermediate). Outputs are rebuilt from the names and types stored inside. - Outputs -
value_1,value_2, … growing dynamically to match the connected Pack. Each output's type is copied from the original Pack input, so you wire them straight into the normal downstream sockets.
Where you'd use it
Mostly in bigger workflows where a bundle of heterogeneous values travels together. The classic case from the README: build a single Pack carrying model, conditioning, and image, pass it through a selection node, then Unpack right before the sampler instead of dragging five cables around the whole graph. If your graph is small and tidy, it's arguably overkill - the cable count it saves is the whole value proposition.
Installing it
Same pack as everything else here, godmt/ComfyUI-List-Utils. Via ComfyUI Manager, search "ComfyUI-List-Utils" and install. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/godmt/ComfyUI-List-Utils
Restart ComfyUI; it lands under list_utils. No models, no dependencies to install - the pack's pyproject.toml lists no runtime requirements, and this node only reads the graph metadata that ComfyUI already passes in.
Common issues
The outputs are dynamic, so if you drop Unpack down before connecting a Pack, you'll see generic * sockets until the connection exists - wire it up and the sockets reshape. If you route it through an intermediate node and the types stay wildcard, the upstream Pack wasn't discoverable through that chain; connect it more directly and they'll resolve. And a PACK is a plain Python dict under the hood - don't try feeding it into non-List-Utils nodes expecting anything sensible. One more honest caveat: Unpack needs a live graph connection to do its type reconstruction, so it won't recover types from a copy-pasted fragment that lost its links. Connect it fresh and it's rock solid.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| PACK | PACK | Connect a PACK created by the Pack node. Outputs are rebuilt from its saved names and types. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| value_1 | * | A value stored in the PACK. Outputs grow dynamically to match the connected Pack. |