MiniMax H3 Per-Row Mask Patch (Experimental)
The node that makes MiniMax H3 video inpainting actually work — without touching core
- model
- patched_model
Here's the uncomfortable thing about video inpainting in ComfyUI: for a long time, "mask an area and regenerate it" for models like MiniMax H3 meant either waiting for ComfyUI core to support it, or hand-editing ComfyUI's own Python files and re-doing the patch every time you update. MiniMax H3 Per-Row Mask Patch exists so you don't have to. It's a temporary compatibility shim that ports the AbleJones mixed-timestep generation-mask fix into your graph as a plain node - no core edits, no on-disk modifications.
How it works
The trick is called per-row mixed timestep masking, and it's worth understanding at a high level because it's why this behaves differently from an SD-style inpaint. When you regenerate part of a video, the protected rows and the generated rows can't just run on the same denoising schedule - if they did, either the preserved part drifts or the regenerated part looks half-baked. The AbleJones approach pins the protected rows near H3's conditioning timestep (the clean reference state) while the generated rows follow the normal denoising schedule, then runs them through the same transformer blocks together.
Under the hood, the node takes your H3 MODEL, clones it, and installs two wrappers through ComfyUI's patcher-extension API:
- an outer-sample wrapper that snaps the incoming denoise mask to H3's 2x2 latent patch rows (and to audio rows),
- a diffusion-model wrapper that swaps in a masked forward pass which picks a per-row modulation - blending the generated row's timestep and the pinned row's timestep per token.
Because it operates on a clone, only the MODEL this node returns is affected. Any other wire from your original model keeps the untouched version.
Inputs and outputs
There's exactly one of each. Drop your MiniMax H3 model into model and take patched_model straight to the guider your sampler uses. If the connected model isn't MiniMax H3 - or the H3 internals this shim needs are missing after a ComfyUI update - it fails with a clear error instead of silently doing nothing, which is exactly what you want from something this invasive.
Two compatibility details the README is careful to promise: it preserves the block_loop hook that lihaoyun6/ComfyUI-MiniMaxH3-Cache relies on, and it preserves per-block replacement hooks like attention patches on H3 blocks. It also handles both the older H3 audio contract and the newer ModelSamplingAV contract in v0.30.0 builds that dropped time_shift_slope.
The honest caveats
This is an internal-model shim, not a stable API - the README says so in so many words, and calls itself temporary until ComfyUI ships native generation-mask support for H3. When that lands, the instructions are to delete this node and use the core version. In the meantime: run a short generation test after every ComfyUI update, because the H3 internals it wraps are exactly the kind of thing core updates feel free to rearrange. "Experimental" in the display name isn't marketing.
Installing
It's one of four nodes in the ethanfel/ComfyUI-MiniMaxH3-PerRowMasking pack. Grab it via ComfyUI Manager (search ComfyUI-MiniMaxH3-PerRowMasking) or:
cd ComfyUI/custom_nodes
git clone https://github.com/ethanfel/ComfyUI-MiniMaxH3-PerRowMasking.git
Restart ComfyUI. No extra Python dependencies. You'll also want the pack's MiniMaxH3SetGenerationMask node in the same graph - the patch tells the sampler how to do per-row masking, but the mask itself gets attached to the latent by its sibling.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | MiniMax H3 MODEL to patch for per-row mixed-timestep generation masking. Connect this MODEL output to your guider. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| patched_model | MODEL | — |