Nodes/ComfyUI-YogurtNodes/DictMerge (Yogurt Nodes)
ComfyUI Node

DictMerge (Yogurt Nodes)

Slam up to 32 dicts together — and decide who wins the collisions

By yogurt7771·Created 2 years ago·Updated 9 days ago· 1
DictMerge (Yogurt Nodes)
  • dict1
  • dict2
  • dict3
  • dict4
  • dict5
  • dict6
  • dict7
  • dict8
  • dict9
  • dict10
  • dict11
  • dict12
  • dict13
  • dict14
  • dict15
  • dict16
  • dict17
  • dict18
  • dict19
  • dict20
  • dict21
  • dict22
  • dict23
  • dict24
  • dict25
  • dict26
  • dict27
  • dict28
  • dict29
  • dict30
  • dict31
  • dict32
  • merged_dict
overwritetrue

DictMerge takes two dictionaries as required inputs and merges them into one. Then it keeps going - up to 32 optional inputs deep, so you can chain a whole pile of config blobs, API responses, or metadata dicts into a single combined result. It's the "combine everything into one dict" node, and in data-heavy ComfyUI graphs it's the glue that turns scattered JSON sources into one coherent payload.

The question that actually matters here isn't "does it merge?" - it's "who wins when two dicts have the same key?" That's the overwrite toggle, defaulting to true. With overwrite on, later dicts overwrite earlier ones: merge {"a": 1} with {"a": 2} and you get {"a": 2}. Flip it off and the first value wins - {"a": 1} stays, because later dicts only fill in keys that don't already exist. There's no wrong answer; it depends on which source you trust more. Default-on means "the most recent dict is authoritative," which is usually what you want when layering defaults under overrides.

One honest caveat: this is a shallow merge. If two dicts both have a nested dict under the same key, the later one replaces the earlier wholesale rather than merging the inner fields. If you need deep merging, the pack's JsonMerge does recursive merging instead - reach for that when your data is nested.

How it works

It starts with dict(dict1), then applies each subsequent dict in order - update() when overwrite is on, fill-missing-only when it's off. The extra inputs (dict3 through dict32) are dynamically generated under the hood, which is why the node shows as many or as few ports as you need.

Inputs

  • dict1, dict2 - required. Everything after is optional and dynamic: dict3dict32.
  • overwrite - true (default): later dicts win collisions. False: first dict keeps its values.

Output

  • merged_dict - the combined result, *-typed.

Install

Part of ComfyUI-YogurtNodes:

cd ComfyUI/custom_nodes
git clone https://github.com/yogurt7771/ComfyUI-YogurtNodes.git
cd ComfyUI-YogurtNodes
pip install -r requirements.txt

Or search "YogurtNodes" in ComfyUI Manager and restart. Under "Yogurt Nodes" → Logic.

Common issues

  • "The merge lost my value" - collision, and overwrite is on, so a later dict replaced it. Decide which source wins and set overwrite to match.
  • "Nested dicts got clobbered" - shallow merge. Use JsonMerge for deep merges.
  • "I plugged in a third dict and there's no port" - the optional inputs are dynamic; the node should show new ports as you connect them. If not, check for a recent node update.

For combining defaults with overrides, building a unified config from several sources, or assembling the full key set before a DictSubset extraction, this is the node. Just remember the collision rule and you're in good shape.

CategoryYogurtNodes/Logic

Inputs (33)

NameTypeDefaultDescription
dict1*First dictionary
dict2*Second dictionary
dict3opt*Additional dictionary 3 (optional)
dict4opt*Additional dictionary 4 (optional)
dict5opt*Additional dictionary 5 (optional)
dict6opt*Additional dictionary 6 (optional)
dict7opt*Additional dictionary 7 (optional)
dict8opt*Additional dictionary 8 (optional)
dict9opt*Additional dictionary 9 (optional)
dict10opt*Additional dictionary 10 (optional)
dict11opt*Additional dictionary 11 (optional)
dict12opt*Additional dictionary 12 (optional)
dict13opt*Additional dictionary 13 (optional)
dict14opt*Additional dictionary 14 (optional)
dict15opt*Additional dictionary 15 (optional)
dict16opt*Additional dictionary 16 (optional)
dict17opt*Additional dictionary 17 (optional)
dict18opt*Additional dictionary 18 (optional)
dict19opt*Additional dictionary 19 (optional)
dict20opt*Additional dictionary 20 (optional)
dict21opt*Additional dictionary 21 (optional)
dict22opt*Additional dictionary 22 (optional)
dict23opt*Additional dictionary 23 (optional)
dict24opt*Additional dictionary 24 (optional)
dict25opt*Additional dictionary 25 (optional)
dict26opt*Additional dictionary 26 (optional)
dict27opt*Additional dictionary 27 (optional)
dict28opt*Additional dictionary 28 (optional)
dict29opt*Additional dictionary 29 (optional)
dict30opt*Additional dictionary 30 (optional)
dict31opt*Additional dictionary 31 (optional)
dict32opt*Additional dictionary 32 (optional)
overwriteoptBOOLEANtrueWhether later dicts should overwrite earlier keys

Outputs (1)

NameTypeDescription
merged_dict*