Dynamic Mask Input 🎭
Strap as many masks as you like onto one output port
- mask_1
- masks
Mask workflows get messy fast. One mask from a ControlNet, another from a SAM segment, a third hand-painted in the image editor - and now you want to hand a whole collection of masks to a node that expects a mask list. Dynamic Mask Input is the duct-tape port hub for that: plug in one mask, plug in five, and it collects them all onto a single list output without you managing a fixed node with five hardcoded slots.
It's part of the Painting Coder Utils pack, and it's the mask sibling of the pack's Dynamic Image Input 🖼️. Same idea, MASK instead of IMAGE.
How it works
The clever bit is the front end, not the Python. The node starts with a single mask_1 input. When you connect a mask to it, the node's JavaScript adds a fresh empty input port (mask_2, then mask_3...) automatically. Connect to that, and it grows another. The Python side then gathers every connected mask, drops the ones left unconnected (they arrive as None and get skipped), and returns the rest as a list.
If no valid masks arrive at all - say you unplugged everything mid-build - it returns a single blank 512×512 zero mask instead of crashing, which keeps the graph alive but produces an empty-black result downstream. Worth remembering when you're debugging why a batch suddenly came out all black.
Inputs and output
mask_1- the initial required MASK input; more appear as you connect.- Output:
masks- a list of masks (OUTPUT_IS_LISTis true), for nodes that accept mask lists or for feeding batches.
Where it fits
Most commonly you'll use this to assemble masks for batch inpainting or for a node that iterates over a mask list - or simply to keep a pile of masks organized at one point in the graph before they fan out. It's a quality-of-life node, not a processing node; it never merges or composites masks into one, it just gathers them.
That last point trips people up: the name says "Combiner," so newcomers expect the masks to get unioned or multiplied into a single mask. They don't. If you want one merged mask, you want a compositing node (like ImageCompositeMasked/mask combine utilities), not this. This node's job is list assembly, and it does that cleanly.
Install
Via ComfyUI Manager - search Painting Coder Utils - or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/jammyfu/ComfyUI_PaintingCoderUtils.git
Then restart ComfyUI. No models to download; the pack's dependencies (numpy, Pillow, torch, gradio) are already satisfied by a stock ComfyUI. The dynamic-port behavior requires the pack's web/js files to load, which they do automatically - if you've disabled custom node front-ends, you'll only ever see the single mask_1 port.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| mask_1 | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| masks | MASK | — |