Nodes/comfyui-obvpm/Override Bundle Values (obvpm)
ComfyUI Node

Override Bundle Values (obvpm)

Change one field of a preset for one run, without wrecking the preset

By chanon·Created 2 months ago·Updated a day ago· 106
Override Bundle Values (obvpm)
  • bundle
  • wire_1
  • wire_2
  • wire_3
  • wire_4
  • wire_5
  • wire_6
  • wire_7
  • wire_8
  • wire_9
  • wire_10
  • wire_11
  • wire_12
  • wire_13
  • wire_14
  • wire_15
  • wire_16
  • bundle
◄state{}►
◄wires►
◄set►

You've built a workflow around Value Presets - one node holding a named set of settings and handing the lot downstream on a single wire. Then someone wants to run it with 30 steps instead of your preset's 20. Before this node your options were: edit the preset and lose it, or clone the whole preset node and maintain two of them.

Override Bundle Values is the third option. It sits on the bundle wire and changes the fields you nominate for that run, leaving the preset exactly as it was.

The distinction is the point. The preset stays authoritative, the Value Presets node knows it's being overridden (it labels those fields), and next run you toggle the override off and you're back to the preset.

How it works

The bundle comes in; a new bundle goes out with your replacements applied. Editing it in place would be the obvious implementation, and it's exactly what this node refuses to do: a Set/Get pair often hands one bundle to several consumers, so an in-place edit would leak your override into all of them.

Where the overrides come from changes how they're checked:

  • From a Value Presets node, the bundle carries its schema with it. So your override is validated the same way the preset node validates its own values - same range, same decimals, same dropdown choices - and the schema's when lines are re-applied: turning on a field that decides others brings those fields back with the values the preset holds for them, instead of passing their hidden None downstream.
  • From a plain Bundle or a Get, there's no schema, so an override simply takes the type of the value it replaces. A whole number stays whole (typing 0.5 into an int field is an error, by name), a boolean stays true/false, text stays text.
  • Values no widget can hold - an image, a model, a latent - don't get a row at all. They get an input socket: wire something in and it replaces the field; leave it empty and the bundle's own value passes through untouched.

Upstream, the preset node shows the consequence: an overridden field is labelled overridden, and greyed out entirely when every path from that node to a consumer overrides it. When only some paths do, it reads overridden in n of m - the correct answer, since a Set/Get pair can hand one bundle to consumers you didn't override for.

The inputs that matter

  • bundle - required. The bundle to override, from a Value Presets node, a Bundle, or a Get.
  • set - the name other nodes read this bundle by, when you turn on set to constant in the config dialog (an Unbundle with get, or a KJNodes Get, picks it up with no wire at all).

Everything else in the signature is plumbing the browser owns and you should leave alone: state (which fields you chose, which toggles are on, their values) and wires (the field names behind the sockets), plus sixteen sockets, wire_1 through wire_16, of which only the ones you wired appear. Those channels exist so the node survives a reload and works in an API-format prompt without the UI rebuilding anything.

Output: bundle - the overridden bundle, as a new one.

The workflow is: click the gear, tick which fields are allowed to be overridden, then toggle on the ones you want. Off, the bundle's own value passes and the toggle shows it; on, the row under it wins.

Installing it

cd ComfyUI/custom_nodes
git clone https://github.com/chanon/comfyui-obvpm
# restart ComfyUI, then hard-refresh the browser (Ctrl+Shift+R)

Or install from ComfyUI Manager by searching obvpm. No Python dependencies - the pack ships an intentionally empty dependency list rather than re-pinning what ComfyUI already provides. It does ship frontend JavaScript, and this node's whole config dialog is built by it, so hard-refresh after installing or updating. Every node in the pack ends in (obvpm).

Version note: the node is new in 0.2.14; 0.2.15 is what fixed the pack's handling of bundles past sixteen fields. Use 0.2.15 or later.

Where people get burned

The node looks empty. Its rows are drawn at runtime from the bundle you wired in. Empty usually means the frontend JS didn't load (stale cache - hard refresh) or nothing is wired into bundle yet.

You renamed a field upstream and the override went quiet. Overrides match by field name, never by position - that's what stops a reorder from silently reassigning values, but a rename orphans the override. The run log says so either way ("the preset has no field …"); re-tick it after a rename.

Sixteen wired overrides is the ceiling. The socket pool is fixed at sixteen, and only the ones you wired appear. Widget-able fields don't need sockets, so you'll rarely hit it - but an image, model or latent override eats one each.

Fields switched off on the preset node stay off. Value Presets can hide a field on one node without touching the shared schema, and that field is None on the bundle - an override here doesn't resurrect it.

Overriding everything makes the preset pointless. When every path to a field is overridden, the Value Presets node greys it out and stops being its source of truth. That's the graph telling you the truth - but if what you wanted was "presets, with the freedom to nudge," leave the toggles off by default.

Categoryobvpm/bundle

Inputs (20)

NameTypeDefaultDescription
bundleOBVPM_BUNDLEThe bundle to override values of -- from a Value Presets node, a Bundle, or a Get.
stateoptSTRING{}—
wiresoptSTRING—
wire_1opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_2opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_3opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_4opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_5opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_6opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_7opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_8opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_9opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_10opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_11opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_12opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_13opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_14opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_15opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
wire_16opt*A value for the field this socket is named after; it replaces the bundle's. Unwired, the bundle's own value passes.
setoptSTRINGThe name other nodes get this bundle by (an Unbundle with 'get', or a KJNodes Get). Turned on in the config dialog.

Outputs (1)

NameTypeDescription
bundleOBVPM_BUNDLEThe bundle with the overrides applied (a new bundle; the incoming one is untouched).