Unbundle (obvpm)
Open the bundle, and take only the fields you need
- 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
If you're coming from a context-bus pack - rgthree's Context, the pipe in Easy-Use, a RUN_CONTEXT - you already know the shape: one wire carrying many values, and something at the far end that hands them back as separate pins. This is the obvpm version of that second half, and the thing worth understanding about it is that there is nothing to configure on the packing side.
What it does
Wire a bundle into in and the outputs appear, one per field, labelled with each field's name. The names are traced back along the wire to the Bundle node that packed them - the pack reads the field list from the same source in both places, so the two ends can't disagree about what's in the box.
Up to 16 outputs exist as out_1 … out_16, untyped wildcards, so whatever the bundle held - an image, a model, a latent, a string, another bundle - comes out here and plugs into whatever wants it.
Wiring something that isn't a bundle into in is refused, with a message telling you to feed it a Bundle node's output. Bundles are plain name/value mappings underneath, so the check is honest: a dict or nothing.
The config dialog
Right-click → Configure, or the small button on the node, and you get a dialog to reorder the outputs and hide the ones a branch doesn't need. Hiding is also how you take a single field: hide the other fifteen and you've got a clean wires-tap rather than a node with a comb of unused pins. A field that's still connected can't be hidden - unplug it first, which is the right order of operations and stops you from silently killing a link.
Once you've set a layout, it pins the pins. Fields added upstream append at the end instead of shifting the existing outputs around, and a field that disappears upstream while still wired keeps its pin and outputs None (with a log line saying so) rather than quietly re-meaning everything downstream. If you've ever had a graph load with all its wires half a field off, you know why this matters.
The names input is the mechanism behind that: a multiline string, normally left to the dialog, listing the fields to expose in output order. Empty means "the bundle's own fields, as packed."
Tracing, nesting, and laziness
The interesting robustness is in what the trace follows. Names come through a Lazy Case Switch - when every connected branch packs the same field names, which is precisely when the answer is the same whichever branch runs. They come through subgraph boundaries, and they come through KJNodes Set/Get pairs (the Get is followed to its Set, in the same graph or up through the subgraph the Get sits in). Only sockets that could actually be carrying the bundle are followed, so a cases or selected wired in from a Dropdown doesn't make the switch look ambiguous.
Bundles nest. An inner bundle can itself be a field of an outer one; unbundling the outer puts the inner bundle on the output named for that field, and an Unbundle wired there shows the inner fields. The trace goes down as many levels as you've built.
And laziness survives the round trip. A Bundle node sits on a branch, so if that branch isn't selected, the bundle and everything feeding it are skipped exactly as if the values had been wired directly. The abstraction doesn't cost you the pruning.
The failure mode to expect
A bundle is a contract between two ends of a wire, and it's easy to unpack a bundle that was assembled before the thing you care about changed - a context assembled before your LoRA merged, a bundle packed upstream of the node that replaced the latent. With forty explicit wires you can see that the LoRA output isn't feeding the sampler; with one bundle wire, the connection is present and the contents are wrong. That's the tax this pattern charges, and it's the reason the pack ships Peek Bundle: one line per field, shape and type, on the node. Leave it wired to anything you're debugging.
Also: cross-pack context objects don't interoperate. Every pack invented its own type, and OBVPM_BUNDLE is this one's. A bundle from here goes into an Unbundle from here, not into rgthree's Context.
Install
Manager, search comfyui-obvpm. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/chanon/comfyui-obvpm
Restart ComfyUI. No Python dependencies - the pack declares none, since everything it imports already comes with ComfyUI - and no model files. The whole pack lists under obvpm in the node search menu.
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. |