Reorder Batch Mask
Stop guessing which mask is which
- mask
- mask
Batch order is invisible and load-bearing
When a detector hands you a bag of masks, the order they arrive in is an implementation detail you never see - and then it becomes part of your output. Anything downstream that arrives as a list pairs with those masks by index: per-item prompts, filenames, the images you're compositing results back onto. Get the order wrong and image 1 gets face 4's re-render. Nothing errors. It just looks like the model had a bad day.
Reorder Batch Mask is the fix. It permutes a MASK batch - the author's own description: "Reorders a MASK batch from content bounds without changing mask pixels." That last clause is the important promise: it moves whole masks around in the batch, it doesn't touch a single alpha value.
What order actually does
The node takes mask (a MASK batch) and order (a dropdown), and gives back mask in the new order. There are seven orders, and they come in two families.
By size: biggest and smallest sort by the area of each mask's content bounding box - big blob first, or specks first.
By position: left_to_right_top_to_bottom, clockwise, counter_clockwise, clockwise_outward, and counter_clockwise_outward. The first is ordinary reading order across the grid of masks. clockwise and counter_clockwise walk that grid as a spiral from the outside in; the _outward variants spiral from the middle out. If your masks are a face plus four hands, the spiral orders let you produce a consistent "centre first" sequence for whatever consumer needs one.
If you also use SEGS-based packs, this is the same order vocabulary the suite's Reorder SEGS node uses, applied to plain mask batches instead of Impact Pack segments.
How it works
For each mask in the batch it computes the content bounds: quantize to 8-bit and take the bounding box of non-zero pixels. Everything else follows from those boxes.
Size ordering is a plain sort on box area.
Spatial ordering is the interesting part. The node groups the boxes into rows and columns - a box joins an existing cluster only if its centre falls inside that cluster's current span on that axis, which stops two separate groups of blobs from being merged into one fake row - and assigns each mask a lattice cell. Two masks claiming the same cell is a hard error rather than a coin flip ("cannot derive a unique position lattice"), which is genuinely useful: it's the node telling you your layout isn't the grid you thought it was. Masks with no content at all are appended at the end.
Finally it reorders along the batch dimension and returns the batch. Pixel data is never rewritten; the output is a reshuffle.
Wiring it in
The natural upstream neighbour is another node from this same pack: Mask to Mask Batch, which splits a multi-blob mask into one mask per connected region (with a drop_size so single stray pixels don't become batch items). Split, then reorder, and you have a deterministic, human-readable sequence of regions going into a per-region detail pass or a compositing loop. Its output shape is exactly the [B,H,W] batch this node wants, so they connect cleanly.
Downstream, mask goes anywhere a batch of masks goes.
Installing
The repo's README is empty, so ignore it and use one of these. Search ComfyUI-Utility-Suite in ComfyUI Manager (published to the Comfy registry under publisher tom-m), or:
cd ComfyUI/custom_nodes
git clone https://github.com/tom-m-2020/ComfyUI-Utility-Suite
Restart ComfyUI. The only dependency line in requirements.txt is opencv-python-headless - if another pack already installed cv2, leaving it alone is the safer move. No model files. Both nodes appear under Utility Suite/Mask.
Common issues
"expects MASK [B,H,W]" - it wants a real batch, and a single mask is often rank-2. Batch it first (core's Batch Masks, or this pack's Mask to Mask Batch) rather than passing one mask and hoping.
"cannot derive a unique position lattice" - two masks overlap in the same logical grid cell, so there is no unambiguous order. Either fix the layout, or switch to biggest/smallest, which don't care where anything sits.
A blank mask jumps to the front or the back. A fully black mask has no content bounds, so it sorts as zero area: first under smallest, last under biggest and in every spatial order. Worth knowing before you build a filename convention on top of the ordering.
Masks with nothing in them after 8-bit quantization count as blank, too - a mask whose values are all below about 1/255 is empty as far as this node is concerned.
And a general one: the pack is new - a single commit, version 1.4.0, written against ComfyUI's V3 backend node API. If your ComfyUI is old enough to pre-date comfy_api.latest, the suite simply won't load, and there isn't yet a community thread to search for help. Update ComfyUI.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | — | |
| order | COMBO | 7 options: left_to_right_top_to_bottom, clockwise, counter_clockwise, clockwise_outward, counter_clockwise_outward, biggest, +1 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| mask | MASK | — |