Mask Arbiter
Three people in the frame — Mask Arbiter picks the leftmost, the biggest, or the one in the middle
- masks
- mask
- selected_mask
- ordered_masks
You ran GroundingDINO + SAM over an image with three people in it and got back… three masks, because of course you did. Now you want the leftmost person's mask for inpainting, and you're staring at a pile of binary tensors with no way to say which one. That's the exact gap Mask Arbiter fills: it takes a list of masks and hands you back a single mask chosen by criteria you actually care about.
It's the namesake node of SparknightLLC/ComfyUI-MaskArbiter, a small two-node pack. And it's not a reinvention of the wheel - the author ported the [txt2mask] shortcode from his Automatic1111 extension Unprompted into ComfyUI. Same idea, native node graph.
How it works
Mask Arbiter is pure post-processing: nothing is generated, nothing is downloaded, it just sorts and slices masks. Feed it any MASKS or MASK input - from SAM2, Impact Pack's SAM node, BiRefNet, whatever produces a mask list - and it sorts the list, then returns the entry at index (zero-based) after sorting.
Under the hood the sorting is geometry over the mask's nonzero pixels. leftmost and topmost look at the extreme (or, with average on, the centroid) coordinate along the relevant axis; innermost ranks by distance to the image center; largest counts pixels. For speed it downscales masks to resolution pixels for evaluation only - the returned mask is always at your input's original size. merged skips sorting entirely and just unions everything into one mask, which is genuinely handy and easy to overlook.
The inputs that matter
You'll set three things most of the time:
sort_by-leftmost,topmost,innermost,largest,initial(keep order),random, ormerged. Default isleftmost.index- which sorted mask to return, zero-indexed. Values past the end select the last mask rather than erroring, which is friendlier than it sounds.resolution- cap on the evaluation size (default 64). 0 disables it. It only affects sort speed, never the output.
The optional average and reverse are the tweaks: average uses centroids (often the right call for innermost when one mask has disconnected blobs), and reverse flips the sorted order - so "leftmost + reverse" is how you get the rightmost subject. Wire either masks or mask in - the tooltip's plain about it: use one, not both, and mask wins if you connect both.
The two outputs are selected_mask (the one you asked for) and ordered_masks (the whole sorted list, in case you want the runner-up or a different index without re-running the graph).
Installing it
Install the pack once and you get both nodes:
cd ComfyUI/custom_nodes
git clone https://github.com/SparknightLLC/ComfyUI-MaskArbiter
then restart ComfyUI. Easier still, it's on the Comfy Registry, so ComfyUI Manager → Install Custom Nodes → search "ComfyUI-MaskArbiter" does the same thing without touching a terminal. Mask Arbiter itself has no model files and no heavy dependencies - it's torch and numpy doing the math, and it'll work even if you never touch the pack's other node.
Where people get burned
- The "Connect either 'masks' or 'mask'" error is the node telling you nothing's plugged in. If you're wiring from a SAM node that outputs a batch under the
MASKtype, use themaskinput - not all sources exposeMASKS. mergedignoresindexandreverse- after merging there's only one mask to return. Don't fight it.- Sorting gotchas got patched over time -
topmostreturned reversed order in early releases andlargestsorted smallest-first for a while, so if a downloaded workflow behaves oddly, update the pack; you may be on the buggy 0.1.x. - A genuinely empty input now returns a correctly-sized black mask (0.3.0 fix) instead of crashing, but a black mask is still a signal your upstream detection found nothing - check the SAM threshold first.
It's a small node, but it's the difference between "the workflow produces masks" and "the workflow produces the mask I wanted." For automated pipelines that do per-object inpainting or compositing, that's a real bottleneck you just deleted.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| sort_by | COMBO | leftmost | Order masks before selecting an index. 'merged' returns one union of all masks. |
| index | INT | 0 | Zero-based index to select after sorting. Values past the end select the last mask. |
| resolution | INT | 64 | Maximum width or height used only for sorting. Use 0 for full resolution; outputs retain their original size. |
| masksopt | MASKS | Mask list or batch to sort. Ignored when 'mask' is connected. | |
| maskopt | MASK | Standard ComfyUI mask batch. Takes precedence over 'masks' when both are connected. | |
| averageopt | BOOLEAN | false | Use each mask's centroid for positional sorting. Otherwise, use its nearest relevant edge or pixel. |
| reverseopt | BOOLEAN | false | Reverse the final mask order before selecting the index. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| selected_mask | MASK | — |
| ordered_masks | MASKS | — |