ComfyUI Node

Dynamic Pipe Any Node

A pipe that's just a list — build it, pad it, unpack it

By inkbottle-9·Created 8 months ago·Updated 12 days ago· 1
Dynamic Pipe Any Node
  • pipe
  • pipe
ports_count2

ComfyUI has a whole family of "pipe" nodes - rgthree's Context, Efficiency's bundled model/clip/vae tuple - and they're all the same idea: gather a bundle of values onto one wire so a graph doesn't become forty parallel noodles. This node is the generic version. A pipe here is literally just a Python list, no special structure, no model/clip/vae contract. You build a list, ship it down one wire, and pull it apart at the other end.

That sounds almost too simple, but it's exactly what you want when you're feeding data into the pack's DynamicScriptNode: drop a list of prompts, conditioning, or numbers into one port, do real work on it in Python, and hand it back out. Because the pipe is a plain list, every other *-typed node can touch it - it doesn't commit you to any pack's pipe format.

How it behaves

Set ports_count (0–100) and the node grows a matching set of ports. Each run it:

  1. Takes your incoming pipe (any Python list - or nothing).
  2. Pads it with Nones if it's shorter than ports_count, or trims it if longer.
  3. Overwrites positions with any connected input_* port that isn't None.
  4. Outputs the finished list as pipe, plus every item on its own output_* port.

So the input_* ports are "patch" inputs - they replace slots in the list rather than append to it - and the output_* ports are the unpack. Wire the whole list into one place, or unpack individual slots into separate consumers. Both, if you like; the node is happy to serve the list and its parts simultaneously.

Note that the fixed schema only lists the single pipe output - the output_* and input_* ports are generated dynamically by ports_count, which is why you won't see them enumerated anywhere.

The inputs and outputs that matter

  • ports_count - the size of the list and the number of port pairs. This is the one you actually set.
  • pipe (optional) - the incoming list. Accepts any Python list; leave it unwired to start from an empty list.
  • pipe output - the final list.
  • output_* - each list element on its own socket.

Where people get burned

  • None slots are meaningful, not an error. If a slot ends up None, that's the value - downstream nodes that choke on None will choke. That's also the difference from a merge: this node doesn't concatenate lists, it positions items.
  • It always reruns. Change-detection returns NaN, so the node rebuilds the pipe every queue run and marks everything downstream dirty. Cheap for a list, but don't hang a chain of these off a huge workflow and wonder why the cache never engages.
  • It's not a context bus. It won't carry a model alongside a latent in one typed bundle the way rgthree's Context does; it's a dumb list. If you need typed bundle semantics, that's a different node - use this one when "just a list" is exactly the point.

Install

Same pack, zero dependencies:

cd ComfyUI/custom_nodes
git clone https://github.com/inkbottle-9/comfyui_dynamic.git

restart, or search comfyui_dynamic in ComfyUI Manager. A small, solo-maintained, LGPL pack - the pipe node is one of its simplest and most dependable parts.

Categorydynamic/utils

Inputs (2)

NameTypeDefaultDescription
ports_countINT20–100The number of port-pair for this node.
pipeopt*The pipe in. Accept any Python list or tuple.

Outputs (1)

NameTypeDescription
pipe*Essentially outputs a Python list.