Unbundle (obvpm)
The outputs name themselves
- in
- out_1
- out_2
- out_3
- out_4
- out_5
- out_6
- out_7
- out_8
- out_9
- out_10
- out_11
- out_12
- out_13
- out_14
- out_15
- out_16
A Bundle node packs several values into one wire. Unbundle is the other end: connect the bundle and the outputs appear, already labelled with whatever was packed - model, latent, mask, your own renamed fields. There's no list to type in and nothing to keep in step with the packing side.
Which is the opposite of how the pipe-style nodes in other packs behave, and it's what drives everything below.
How it knows the names
A bundle is an ordered name/value mapping, so the field names are already on the wire. The node's outputs are built in the browser by tracing that wire backwards to whichever node packed it; the server side reads the same keys off the bundle in the same order. Both ends are looking at one list, which is why they agree without you maintaining anything.
The trace is more persistent than you'd expect: it follows the wire through subgraph boundaries, through KJNodes Set/Get pairs, and through a Lazy Case Switch - that last one only when every connected branch packs the same field names, which is exactly when the answer is the same whichever branch runs. Branches that pack different fields have no single answer, so no names are offered and you give the consumer an explicit list instead, matched by name.
Inputs and outputs
in takes the bundle. It's required and it's strict: wire anything that isn't a name/value mapping into it and the node refuses rather than guessing.
names is optional and normally invisible - the config dialog writes it. One field per line, in output order; leave it empty and you get the bundle's own fields as packed. This is also the switch for taking a subset: hide the fields a branch doesn't need and only those get exposed.
The outputs are out_1 through out_16, all typed as wildcards (*). Sixteen matches Bundle's ceiling, so you won't hit it from this side. The wildcard typing is convenience with a catch: ComfyUI will let you plug an output into anything, including something wrong.
The config dialog is the other half of the node
Click the ⚙, right-click → Configure…, or double-click the node: you get the field list, where you can reorder and hide. Two behaviours matter:
- Reordering moves the wires with their fields. A wire carrying
maskstill carriesmaskwherever it ends up. You're rearranging labels, not shuffling values by position. - Hiding is how you take a single field. A field with something connected to it can't be hidden - unplug it first, deliberately, so a live wire can't disappear behind a checkbox.
Once you've set a layout, it also pins the outputs. Fields added upstream later append at the end instead of shifting every pin down; a field that disappears upstream while still wired keeps its pin and outputs None (with a log line naming it) rather than silently re-meaning everything below it. That's the behaviour you want, and it's the opposite of what most people expect from a dynamic-socket node.
Debugging what comes out
When an output is None, ask whether the bundle ever had that field. Peek Bundle, from the same pack, prints every field name and a one-line shape summary onto its node body - hang one off the same bundle wire. The log is the second place to look: Unbundle logs which names it asked for and which the bundle didn't have.
Bundles also nest: put a bundle inside another bundle and a second Unbundle on that field exposes its members - the trace follows back through the outer Unbundle to whichever Bundle packed it, at any depth.
Installing it
cd ComfyUI/custom_nodes
git clone https://github.com/chanon/comfyui-obvpm
Restart, or install through ComfyUI Manager by searching comfyui-obvpm. No Python dependencies - the pack's list is deliberately empty, since everything it imports ships with ComfyUI. The class id is Unbundle (obvpm); searching the node menu for obvpm lists the whole pack.
Common issues
"Expected a bundle" on the input. You've wired a raw value - an image, a latent - into in. Only a Bundle-family output goes here. Unbundle is also the node that refuses unsaved/renamed field wiring loudest, so read the log rather than assuming the node is broken.
An output is None and you can't see why. Either the field was renamed on the packing side (names are matched exactly), or you're downstream of a case switch whose branches pack different fields, in which case your names list is doing the matching and one branch simply doesn't have that key.
No outputs appear at all. The client-side trace failed - which happens when you paste an Unbundle into a fresh workflow with nothing connected. Connect the bundle and they populate.
Nodes from a workflow saved before 2026-09-13. The pack renamed all its class ids in 0.2.0 after an id clash with another pack's Bundle node; old workflows migrate automatically on open, and an API-format prompt is rewritten server-side. If the Bundle node still doesn't work after the migration, delete it and create a new one.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| in | OBVPM_BUNDLE | The packed value from a Bundle node. | |
| namesopt | STRING | Written by the config dialog: the fields to expose, one per line, in output order. Empty = the bundle's own fields as packed. |
Outputs (16)
| Name | Type | Description |
|---|---|---|
| out_1 | * | The bundle's value for field 1. |
| out_2 | * | The bundle's value for field 2. |
| out_3 | * | The bundle's value for field 3. |
| out_4 | * | The bundle's value for field 4. |
| out_5 | * | The bundle's value for field 5. |
| out_6 | * | The bundle's value for field 6. |
| out_7 | * | The bundle's value for field 7. |
| out_8 | * | The bundle's value for field 8. |
| out_9 | * | The bundle's value for field 9. |
| out_10 | * | The bundle's value for field 10. |
| out_11 | * | The bundle's value for field 11. |
| out_12 | * | The bundle's value for field 12. |
| out_13 | * | The bundle's value for field 13. |
| out_14 | * | The bundle's value for field 14. |
| out_15 | * | The bundle's value for field 15. |
| out_16 | * | The bundle's value for field 16. |