MiniMax Director — Refit for the refine
The node that stops the upscale pass dying with a shape mismatch
- positive
- latent
- vae
- positive
If you flipped the Upscale switch in the MiniMax Director workflow and the refine pass blew up with shape mismatch: value tensor of shape [988, 96] cannot be broadcast to indexing result of shape [2035, 96], this is the node that fixes it. One job, three inputs, no settings. It is the least glamorous node in the pack, and the moment you need it, it's the only one that matters.
Why a two-pass render needs a node like this
Two-pass rendering is old and boring and correct: generate at the size the model is happy with, enlarge the latent, refine there, so detail gets added at the bigger size instead of a small picture being stretched. Same hi-res-fix logic people have run since SD 1.5, just moved into latent space - the Director graph upscales H3's latent straight to its megapixels target and refines there, no round trip through pixels.
The wrinkle is keyframes. A picture attached as a first frame or last frame isn't a reference the model reads beside the prompt; it's a frame of the output, and H3 lays a keyframe's rows out on the grid of the latent it is sampling. The Director encoded that picture at the timeline's size (1344×768 by default) because that's what pass one samples. Pass two samples a bigger latent with the same conditioning. Two grids, one conditioning, and the model can't index one with the other - that's issue #4 in the repo, and the error above is what it looks like in your console.
How it works
The node walks every (text, extra) pair in the conditioning you hand it. In extra it looks for minimax_keyframes. Each keyframe is decoded with the VAE, scaled to exactly the pixel size of the latent being sampled - the code reads the latent's height and width as cells × 16, which is H3's cell size - and encoded again. resolved_frame_index and everything else on that keyframe survive the round trip. The text tensor, the reference list, the frame count: all passed through as they were.
No keyframes, and the conditioning comes back untouched - the same object, not a copy. Nothing is modified in place either, so re-queuing at a bigger upscale factor doesn't stack up edits.
The inputs and outputs that matter
- positive - the Director's
positiveoutput. - latent - the latent the refine pass is about to sample: the upscaled one, with the audio half rejoined.
- vae - the video VAE that the Director was given. Not the audio VAE. H3 decodes picture and sound with separate VAEs and the keyframes are pictures.
- positive out - into the
BasicGuiderthat feeds the refine sampler. That's it.
In the shipped graph: Director positive → Refit; Separate AV Latent → upscaler → Concat AV Latent → Refit's latent (the same latent feeds the refine sampler's latent_image); the video VAELoader → vae; Refit's output → the second BasicGuider, whose sigmas are a Simple 8-step schedule split at step 4 by SplitSigmas. Those two core nodes show up as Separate AV Latent and Concat AV Latent even though the workflow JSON calls them LTXVSeparateAVLatent and LTXVConcatAVLatent.
Installing it
It ships in the pack, so there's nothing node-specific to install:
cd ComfyUI/custom_nodes
git clone https://github.com/imbutus/ComfyUI-MiniMaxDirector.git
Restart, or search ComfyUI-MiniMaxDirector in ComfyUI Manager. The pack has no Python dependencies at all - the project's own dependency list is empty, it's pure Python over ComfyUI's built-ins. It needs ComfyUI 0.31.0 or newer if you want the workflow's Turbo path (0.30.0 has the H3 nodes).
What you do have to install is the Upscale branch's one third-party piece: LBH-123-AI/Comfyui_Minimax_h3_latent_Upscaler plus its 691MB minimax_h3_latent_upscaler_3d_fp16.safetensors in models/latent_upscale_models/. Load the shipped workflow without it and you get a Missing Node Types dialog and one red node - expected, harmless while Upscale is off. The four H3 weight files (diffusion model, Qwen3-VL encoder, video VAE, audio VAE) come from Comfy-Org/MiniMax-H3 and have to keep the exact filenames the workflow asks for. Also worth knowing before you spend a weekend on it: H3's weights are licence-restricted, with the US, EU, UK and South Korea outside the licensed territory.
Where people get burned
- The mismatch is still there. Then the refine pass isn't reading this node's output. Check the second
BasicGuider's conditioning comes from the Refit, not straight off the Director. - You wired the audio VAE in. The tooltip is the tell: it wants the video VAE the Director was given.
- You added it to pass one. Harmless but pointless - the latent is the timeline's size, so the scales cancel and you pay for a VAE round trip. It exists for the enlarge.
- A clip with no first/last frame. Nothing to refit, conditioning passes straight through. Don't go hunting for a bug.
- Expect a small precision cost. Core's lanczos scale runs through 8-bit, so a keyframe's values come back accurate to about a code value. Irrelevant next to what the refine pass costs.
- It's new and unproven at large sizes. The author says so plainly. Check a short clip before trusting it with a long one - the refine pass is a real render at the bigger size, so it costs VRAM and GPU time, not just the 691MB download.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| positive | CONDITIONING | The director's `positive`. | |
| latent | LATENT | The latent the refine pass samples -- the upscaled one, audio rejoined. | |
| vae | VAE | The video VAE the director was given. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| positive | CONDITIONING | — |