CivArchive

    Support

    Everything here is free and stays free — the format spec, the nodes, the workflows, the cartridges, the LoRAs. If it saved you a night of debugging (it contains several hundred of mine), tips keep the 5090 warm:

    What is new in 2.2.3

    Long chains finish now. Three separate faults could waste a long render after every expensive stage had already succeeded — sampled, upscaled, normalised, and then nothing written. All three are closed.

    • A host-RAM ceiling. The finished timeline was assembled by allocating a second complete copy of itself. Six shots of 243 frames upscaled needed ~70 GB of system RAM at the final step and died on any 64 GB machine. Now ~21 GB. Twelve shots of 192 frames: ~58 GB down to ~31 GB.

    • An activation reserve that inflated its own estimate. If your chains got slower shot by shot until they crawled, this was why — the measurement counted offloaded weights as free activation space, and each overestimate made the next one worse.

    • Two switches that did nothing. sol_attn and chunk_ffn shipped ON while the nodes they gate ship bypassed. Reported by sdktertiaire2.

    Every one of these was found by someone running the pack rather than by me testing it, which is worth saying plainly. 2.2.1 and 2.2.2 — three crashes on long or high-resolution chains, and reference renders forcing glasses onto people — came the same way. The version notes carry the detail.

    Which DiT to run

    If you are on ComfyUI 0.32 or newer, the comfy-native w4a8 build is the one to use. It is 12.5 GB against Q5_1's 21 GB and measured 27% faster at matched shape and seed — independently, on a 5090 and on a 3090. It also loads through ComfyUI's own path rather than the GGUF loader, and needs no custom node to load. On ComfyUI 0.30 it will not load at all (that format did not exist yet); use a GGUF there, or update.

    Write a scene. Get one continuous take back - picture and audio, no visible cuts, no colour shift between shots, and faces that hold without supplying a single reference image.

    MiniMax-H3 generates blocks of roughly 10-15 seconds. This pack chains them into a scene of any length and joins them so the result reads as one unedited camera take rather than a cut sequence. One script in, one master video out, with a matching audio file.

    Two independent video-understanding models were shown a four-shot chain blind, with no context. Both described it as one continuous unedited take - no cuts, colour consistent, audio unbroken.

    What is new in 2.2

    Everything since 2.1.2, which is where most people still are. Seven point releases folded into one version: five separate defects that stopped the workflow running, a measured campaign against drift over long chains that changed the shipped defaults, and a whole ComfyUI version this pack could not previously run on.

    Five things that stopped it running

    • the Audio Spine produced static on ComfyUI 0.32.0 - that version scales the audio half of the packed latent onto the video schedule, and everything this pack injects was in the stream's native domain, so it landed four times too small and decoded as noise. Three injection sites, not one.

    • naming an mmproj file broke GGUF text encoders - the explicit path skipped the vision key-renaming step, so the tower loaded under names nothing downstream reads. The bitter part: that setting is documented as the escape hatch for when automatic pairing fails.

    • The value 1 for reference_image_size is not available - saved widget values written against an older layout, reading two slots early.

    • the full workflow needed a node from a pack that is not in the zip. A node whose class is missing fails the entire prompt, so without ComfyUI-Custom-Scripts the graph could not be queued at all - for the sake of an on-canvas text box.

    • H3_Seamless_Chain_CORE could not be queued at all, since 2.1.3. Its sampler still carried the widget array from before four dials were removed, so output_scale received false against a minimum of 1.0. The workflow advertised as the one with no third-party dependencies was the one that could not run - and it survived because nobody had ever rendered it. All three bundled workflows are now submit-tested against a running server as part of the release routine, and CORE has rendered: three chained shots, 370 frames, picture and audio.

    Drift over long chains, measured

    Chained shots accrete detail: each one conditions on the previous shot's own output, so invented texture compounds. Measured over ten shots at 960x544, the memory bank's recency slots turned out to be the carrier, and turning them off is strictly better - texture drift per hop 1.055 to 1.022, chroma 1.086 to 1.039, framing correlation at shot ten 0.976 to 0.995. The important part is that at the old default the drift accelerated, which is what a runaway feedback loop looks like, and at the new one it holds flat. Motion continuity was the obvious worry, since carrying it is what those slots are for; tested on a scene with continuous large-amplitude movement, anchor-only retained motion slightly better. So memory_frames now ships at 0.

    Two more defaults changed with it. master_normalize gains a luma+contrast mode, because matching only the mean masks a contrast ratchet compounding underneath it, and pin_renorm holds each pinned latent at shot one's sigma rather than letting the pin's own sigma climb every hop. New dials: pin_frames, pin_noise, pin_renorm. Residual drift is about 1.02 per hop - not zero, and said plainly.

    join_anchor_noise and handoff_release now ship at 0 because they are inert under context_pin: one noises keyframes the mode never creates, the other belongs to a different continuity mode. A non-zero value on a dead control reads as a tuned setting.

    ComfyUI 0.32.0

    Supported, and it needed real work rather than a version bump - see the Audio Spine fix above. 0.30.0 is unchanged and still supported, and 0.33.1 is now in production use on a second machine - a user has confirmed 0.30.0 on Ubuntu as well. Both are now tested before a release goes out, because three of the last four user reports were things that only appear on a runtime that was not being tested.

    Bypassed nodes now say what they need

    Four nodes ship bypassed because their packs are not in the zip. That is the right default - a bypassed node is dropped from the prompt entirely, so the graph queues without them - but a bypassed node sitting on the canvas invites you to un-bypass it, and doing that without the pack installed breaks the workflow with no explanation. The group title, each node's own title, a note above the cluster and the VRAM / SPEED note now all say which pack each one needs. The part people lose: it takes two steps in order - install the pack, Ctrl+B to un-bypass, then turn its switch on. Neither step works alone.

    What is new in 2.0 and 2.1

    Seamless joins, by a different mechanism

    Earlier versions chained by handing the next shot the previous shot's last frame. That still works and is still here. 2.0 adds context_pin: the previous shot's last 22 frames ride into the next shot as raw latents - bit-identical, never decoded to pixels and re-encoded - placed at interior keyframe coordinates, alongside a timeline-placed audio reference. The regenerated head is trimmed on decode. Colour, motion and voice cross the join as data rather than as a description.

    Seam audio that does not clip words

    The boundary audio cut used to land blindly at the start of the incoming shot, which shaved the attack off any word the model placed there. It now lands in the quietest gap inside the shot's first 0.75 seconds, then welds with a 40 ms equal-power crossfade. A line that begins early survives.

    A VRAM and speed panel

    Try a render with every switch off and the reserve at 0 before touching any of this. That is the verified recipe, and in practice the fastest route to a working chain - the activation reserve measures each shape and conditioning payload as it renders and sizes the pool itself, and it holds on 24 GB cards as well as 32 GB. These switches exist to dig out of a spill the console has already named, not for pre-emptive tuning.

    One panel with three lazily gated model patches - memory-efficient attention, chunked feed-forward, and a block cache - plus an activation-reserve control. Every switch off reproduces the shipped recipe exactly, and an off gate means the patch node never executes at all.

    An activation reserve that understands payload

    Memory measurements are now keyed by shape and conditioning payload, so a bare first shot and a reference-laden later shot no longer share one estimate. A measured pool is no longer overridden by a fixed floor, an unseen payload variant estimates from a measured sibling, and - the important part - a spill into system RAM is detected and named in the console instead of presenting as an unexplained five-times slowdown.

    Boundary rules the prompt writer applies for you

    The LLM prompt writer gained a join_style control. Set it to a chained style and the render-verified join rules are appended to its system prompt automatically, so generated scripts obey them without you memorising anything.

    How identity holds with no reference images

    This is the part most people do not expect. A 40-second two-character scene held both faces across every shot with zero reference images supplied. Two mechanisms do it, and neither works alone.

    • The frame relay carries the instance. Every shot begins from an actual rendered picture of the character - the previous shot's last frame - so the specific face, the wardrobe weathering, the exact hair propagate as pixels rather than being re-imagined from text. Drift can only accumulate per join, not per frame.

    • Verbatim text carries the category. Repeating each character's appearance description word-for-word in every shot re-asserts everything a picture cannot pin down, and authors anyone who walks into frame partway through. Once they are in a handed-over frame, they join the relay too.

    Reference images and the identity bank are still there for long chains, characters who leave frame for a long stretch, or when you need a specific pre-existing face - they are just no longer the price of entry.

    Voice identity across the chain

    Chained shots used to re-perform the voice from text each time, and it drifted. Two controls end that, and the shipped default turns one of them on:

    • voice_ref - feed a clean solo speech clip and it anchors every shot as <Audio 1>. Mono clips, sample rate and length are all guarded internally.

    • self_anchor_voice - no file at all. Shot 1's own rendered voice becomes the reference for every later shot. Write shot 1 so the character speaks a clean solo line.

    Both ride the checkpoint's reference rows, so they need ref2va. On fl2va they do nothing except cost tokens - see the checkpoint note below.

    Which workflow

    Three, each with one clear reason to exist.

    • H3_Seamless_Chain_v2 - everything. Master controls, the LLM writer, VRAM panel, identity and voice anchors, an episode/batch prompt source, FFLF boundary plates and an audio spine. The optional lanes ship gated off, so the default path stays simple.

    • H3_Seamless_Chain_CORE - the same job with zero third-party packs. Type your shots into the script box and queue. Start here if you want a render before installing anything else.

    • H3_Keyframes - a different job: a hand-built sampling graph for anchoring a single clip at chosen frame positions with per-anchor condition strength. Not multishot, does not chain.

    v2 supersedes the older H3_Multishot_AIO and H3_Multishot_MEMORY graphs - every lane they had is in v2. If you have them open from a previous version they still work; there is simply no longer a reason to reach for them.

    Keyframes at any position

    Anchor images are not limited to the first and last frame. The pack can place them at arbitrary positions, with per-anchor condition strength. Two implementations exist for the underlying layout patch - this pack's own, and the one in ComfyUI-H3-Motion-Context - and they patch the same place, so exactly one owns it at a time. If Motion Context is installed it wins (its version is a superset) and this pack stands down with a line in the log. If it is not installed, this pack fills the gap. Either way, first and last anchors always work and you never have to choose.

    Master controls, and the dials that matter

    One panel drives resolution, frames per shot and steps for the sampler, and also feeds the writer so it paces dialogue to the real shot length. The dials worth knowing:

    • continuity - context_pin (raw-latent join, needs the Motion Context pack), first_frame (the model's own trained hand-off, no extra pack), cut for episodic work, or flf_chain for boundary plates.

    • seed_per_shot - leave it on. Measured: varying the seed per shot holds the face; one seed for every shot drifted both face and voice. Identity lives in the conditioning, not the seed.

    • chain_gain_control - set to flatten past about five shots. Each shot's tail anchors the next and the model returns roughly 1.3x the anchor's texture energy, so sharpness ratchets across a long chain with a visible step at every seam.

    • output_scale / upscale_model - upscaling happens after decode, per shot, so it works with every continuity mode including context_pin, and a long chain never holds a full upscaled master in memory at once. output_scale is a lanczos resize (measured 1.78x faster than rendering the same output size natively, and visibly softer - resolution, not detail); upscale_model takes ComfyUI's own Load Upscale Model (ESRGAN and friends) for synthesized detail. The old two_pass_upscale is gone - it interpolated the raw latent between passes and produced colour noise in every configuration tested.

    • master_normalize - leave it at luma+contrast. It levels both the brightness AND the contrast of the finished chain against one global target taken from shot 1. Chained shots drift brighter-edged every hop; matching only the mean re-centres that and hands the next shot a higher-contrast start. Measured: texture growth per hop 1.126 -> 1.047 at 960x544 and 1.130 -> 1.055 at 640x352, with contrast spread across shots falling from ~11% to under 0.5%. It runs on decoded frames against per-frame statistics, so there is nothing to tune per resolution.

    • pin_noise - small and scene-dependent, not the anti-ratchet answer it was billed as in 2.1.5. Measured -1.8% per hop at 640x352 and -0.9% at 960x544 on a detail-heavy scene, and it gets worse above 0.10. Leave it at 0.05 or set 0; either way the contrast pass above is what does the work.

    • memory_frames - leave it at 0. The bank's RECENT slots hand each shot's accreted output forward as reference images on top of the pin, so invented detail compounds. Ten shots at 960x544, 2 -> 0: texture 1.055 -> 1.022 per hop, chroma 1.086 -> 1.039, framing at shot 10 0.976 -> 0.995, and the drift stops accelerating. Tested on a moving scene too - motion continuity did not suffer. Raise to 1 only if a busy scene loses continuity between shots.

    • pin_frames - leave it at 22. Longer pins also cut the sharpening, but the head trim scales with them, so 39 frames of audio get cut per join and speech planned under the replay gets clipped.

    • Audio drifts the other way: chained audio gets duller per hop where chained video used to get sharper (measured 8-50% of 4-10 kHz energy lost over 8 shots, seed-dependent). There is no per-shot dial for it - the per-shot correctors were removed in 2.1.3 because they cannot reach the raw-latent pin that carries the drift. For cut-grammar content it can be avoided outright: continuity=cut with bank_pinned=1, memory_frames=0 conditions every shot's audio on shot 1 alone - measured flat.

    • preview_first_shot - writes shot 1 the moment it decodes, so a bad take can be cancelled before the whole chain renders.

    Which checkpoint

    ref2va ships as the default: it carries the reference rows that voice anchoring and the identity bank need. fl2va is lighter and faster, has no reference rows, and chains just as well - the voice rides the frame relay instead of being pinned. Blind review passed on the fl2va configuration; ref2va ships as default because it makes identity explicit rather than emergent.

    Writing a script

    One prompt per shot, --- on its own line between them. The mechanics of a join are handled for you; whether the join reads as invisible is decided by the writing. These rules were each written after a specific failure:

    • The airlock. Every shot after the first opens holding the previous shot's exact closing arrangement, with about two quiet seconds before anyone speaks. The head of a chained shot is discarded on decode - anything you put there is thrown away.

    • Give the hold something to do. A held framing with nothing happening renders as a literal freeze. Write in a breath, a weight shift, an eyeline change.

    • Land settled. End each shot back in a stable arrangement, dialogue finished, about two seconds spare.

    • A line never straddles two shots. Budget it: dialogue at natural pace plus four seconds of quiet must fit. At 362 frames (~15.1s) that is roughly 27 words; at 243 frames (~10.1s), roughly 15.

    • Repeat the descriptions word-for-word. Each character's appearance and the room and lighting, identical in every shot. Rewording between shots is the single most common cause of a face changing mid-scene.

    Camera cuts inside a shot are free and share one audio bed - so put cuts inside shots, and continuity between them. A worked four-shot two-hander ships as example_script.txt.

    Quick fixes

    • A word clips at a join - the script put dialogue too close to a boundary. Move the whole line, do not split it.

    • Sharpening increases every shot - the texture ratchet. Set chain_gain_control to flatten.

    • A render stalls at 0 steps, or runs several times slower than usual - the activation reserve is too small and the driver is paging to system RAM. Raise the VRAM reserve (roughly 20 on a 24 GB card), drop resolution or frames, or remove reference payload. The console now names this when it happens.

    • LLM API error 404, model not found - the writer's model_name is not pulled on the endpoint it is pointed at. See the prompt-writer section above.

    • Red or missing nodes - an optional pack is not installed. The four optional nodes already ship bypassed, so this only bites if you un-bypassed one: re-bypass it with Ctrl+B, delete it, or use the CORE workflow.

    • A render crawls, GPU pinned at 100% but drawing a fraction of its usual power - the weights and the activation pool together do not fit, and the shortfall spills to system RAM rather than raising an error. The console names the clamp when it happens: if the reserve was clamped below the measured pool, that render will not finish in reasonable time. Drop frames or resolution, turn the accelerator switches on, or load a smaller quantisation of the DiT - a 4-bit checkpoint frees several GB for activations, which is usually the whole difference.

    • GGUF architecture error - the pack teaches ComfyUI-GGUF the minimax_h3 architecture at startup, so installing it is normally the whole fix. If the error persists, run python apply_gguf_arch_patch.py from the pack folder once and restart.

    • Audio dulls on a very long chain - expected; restart the chain on a scene cut, where a fresh start costs nothing.

    The prompt writer needs a model you actually have

    The full workflow ships pointed at a local Ollama with model_name = qwen3:14b. Pull it before the first queue or the run stops immediately with LLM API error 404: model 'qwen3:14b' not found:

    ollama pull qwen3:14b

    Any OpenAI-compatible endpoint works - put its URL in base_url and the exact tag in model_name; ollama list prints the tags you have and it must match character for character. A remote or hosted endpoint is often the better choice, because a local writer large enough to be good competes with H3 for the same card and on under 32 GB will evict the model mid-render.

    Running the writer locally? Turn on unload_model_after on the writer node. It frees that model from Ollama the moment the script is written, so the video model gets the card - otherwise it sits for the server default of five minutes, which is your whole first shot. ComfyUI's own eviction cannot reach it (separate process), and Ollama's OpenAI-compatible endpoint has no keep_alive field to ask with; the switch uses the native endpoint. It is added to the writer at runtime by this pack, and is off by default.

    Want no LLM at all? Set the master panel's use_file_prompts to manual entry, delete the writer, and feed your own shot script straight into the sampler's script input - one prompt per shot, separated by --- lines. The CORE workflow already works this way.

    Requirements

    Always: ComfyUI v0.30.0 through v0.33.1 - tested at three points (0.30.0 on Ubuntu by a user, 0.32.0 here, 0.33.1 in production on a second box) and supported across the range (native MiniMax-H3 support), this node pack, a MiniMax-H3 checkpoint, the H3 text encoder, and the video and audio VAEs. The CORE workflow needs nothing else - it is built from this pack plus stock ComfyUI nodes.

    For the FULL workflow. ComfyUI validates every node class in a graph before it will queue, so a missing pack stops the whole workflow - not just its own feature. Each can be removed instead; INSTALL.md gives the one-widget change or node deletion for every entry.

    • ComfyUI_JoyAI_Echo_GGUF_Nodes - the LLM prompt writer (JoyEcho_LLMEnhance). It is inside the release zip - copy it into custom_nodes/ with the main pack. It is RealRebelAI's pack, modified with attribution (the NOTICE inside lists every change); use that copy, not upstream - the workflow drives inputs the upstream release does not have, and with upstream those values are dropped silently. Hand-written scripts can delete the writer instead.

    • ComfyUI-H3-Motion-Context - continuity = context_pin, the shipped default, plus interior keyframe anchors. Removal: continuity = first_frame.

    • RES4LYF - the beta57 scheduler the full workflow ships with. Removal: scheduler = beta (measured cost: lip-sync 8/10 vs 10/10, everything else equal; CORE ships beta already).

    • ComfyUI-sol-attn and comfyui-minimax-h3-blockcache-T8 - the VRAM/SPEED patch switches. The switches ship OFF and the nodes ship bypassed, so the graph queues whether or not you have either pack - a bypassed node is dropped from the prompt entirely. To use one: install its pack, restart, Ctrl+B the node to un-bypass it, then turn its switch on. Both steps, in that order - neither works alone.

    • ComfyUI-Custom-Scripts - the in-canvas script preview, a leaf node; removal: delete it.

    • ComfyUI-GGUF - quantised checkpoints and encoders.

    Models

    GGUF quants of the H3 checkpoint are at huggingface.co/joeygambino/MiniMax-H3-GGUF - Q8_0 for 32 GB, Q5_1 for 24-32 GB, Q4_0 for 16 GB. The text encoder and both VAEs are at huggingface.co/Comfy-Org/MiniMax-H3. GGUF encoder quants are at huggingface.co/joeygambino/MiniMax-H3-encoder-GGUF; keep the -mmproj vision sidecar, and load it with this pack's H3 CLIP Loader (safetensors + GGUF) rather than the stock GGUF loader - the vision path is what carries frames between shots.

    ComfyUI-GGUF pairs that sidecar by filename, looking only in the encoder's own folder. Rename either file or separate them and the match fails; upstream logs an error and then carries on without the vision tower, which looks like the model ignoring your reference image. This pack's loader raises instead of continuing blind, falls back to the only mmproj beside the encoder when there is exactly one, and gives you an mmproj_name widget to name the file outright - with that set, filenames and folders stop mattering.

    What is verified, and what is not

    Stated plainly, because a release note is a claim.

    • Verified: chained renders reviewed blind by two independent models and reported as one continuous take with consistent colour and unbroken audio; holding on both a static talking head and dynamic moving content; a 40-second two-character scene holding both faces with no reference images.

    • Verified since: all three bundled workflows submit-tested against a running server on ComfyUI 0.30.0 and 0.32.0, with 0.33.1 in production use on a second box; the full workflow rendered end to end from the shipped file on 0.32.0 through both of its script lanes, and read by a blind reviewer as one continuous static take with no cut findable anywhere, correct lip-sync, no drift in framing or colour and clean audio; CORE rendered for the first time at 370 frames.

    • Not verified: the shipped ref2va default is the same chaining mechanism with reference rows added, but blind review ran on the lighter fl2va path. Very long chains dull the audio slightly per hop. flf_chain has not been rendered against a fully colour-matched plate set.

    Credits

    The context_pin join and interior keyframe anchoring build on ComfyUI-H3-Motion-Context by NikoDemon80. The script preview uses ComfyUI-Custom-Scripts by pythongosssss. GGUF loading builds on ComfyUI-GGUF by city96. Thanks to @viralesveras for contributions to earlier versions.

    Free, and it stays free. If it saved you time: Ko-fi · GitHub Sponsors · Liberapay.

    Description

    I update frequently. As soon as I see a bug, I kill it. I apologize for the crazy morning of chaos updates!


    2.1.2 — reference images, per-shot saves, and six repairs

    One new capability and a set of fixes. The chaining itself is untouched: nothing here changes how shots join, so a graph that renders well today renders identically after updating.

    New: reference images actually have a way in

    The sampler's reference_images input has existed since 2.0, and SETTINGS.md documented it — as unwired, because nothing in the shipped workflow was connected to it. There was no way to use it without building the lane yourself.

    The full workflow now carries a REFERENCE lane in the anchors column: two image loaders → ImageBatch → a gate → the sampler. It ships with the gate off, so nothing changes until you turn it on. Point the loaders at portraits of your character, flip the gate, and they ride into every shot as <Picture 1>, <Picture 2>. Chain another ImageBatch for a third and fourth. Needs a ref2va checkpoint.

    Unlike the identity anchor above it, these are not a first frame — they do not constrain shot 1's composition, they only carry who the person is. That also makes them the thing that covers shot 1, where the memory bank is still empty and has nothing to carry identity from yet.

    New: every shot can be saved as it renders

    A chain only became a file at the very end, when the master was muxed. So anything that failed after the last shot destroyed the entire run — and one report was three hours lost to an out-of-memory error at the mux, after every shot had already rendered successfully. The work existed and was thrown away, which is the worst version of that bug rather than the mildest.

    save_every_shot (on both samplers) writes each shot to output/video/H3_SHOTS/ the moment it decodes, alongside the master. If the mux dies you have every shot on disk and a joining job instead of a lost day. Files are written before the seam trim, so consecutive shots overlap by about a second — the master is still the clean join, these are the safety copy. Requested in issue #13.

    New: custom sigma schedules

    The samplers built the schedule themselves from steps + scheduler, with no way to supply your own — so a turbo LoRA that ships the curve it needs could not use it, and ran wrong rather than refusing. Both samplers now take an optional SIGMAS input. Connect one and it replaces the schedule entirely, steps rebinds to len(sigmas)-1 so the two-pass upscale split is taken as a fraction of your curve, and the console states that the steps and scheduler widgets are being ignored instead of silently overriding you. Link-only input, so saved graphs load unchanged. Issue #14.

    Fixed: --- separators were ignored in passthrough mode

    example_script.txt ships --- separated and every document tells you to write scripts that way, but the writer's passthrough path returned the whole file as ONE shot — which the sampler then repeated to fill shot_count. Pasting a finished four-shot script rendered the entire text as shot 1, four times over. It now splits on exactly the same rule the sampler uses. A single paragraph is still one shot, so .txt batches are unaffected.

    Fixed: a stale prompt-set filename killed the whole queue

    ComfyUI validates every combo value in a graph before it runs anything. If RiftPromptSource's saved source_file no longer existed — a renamed folder, a workflow shared from another machine, or the prompt lane simply switched to manual — the queue failed with Value not in list and nothing ran, including the lanes that were perfectly fine. Switching to manual did not disable it, because validation happens before the switch is ever consulted.

    The node now declares VALIDATE_INPUTS, so the filename is resolved only if the node actually executes. Manual mode now genuinely disables it. If it does run and the file is missing, the error names the file.

    Fixed: the writer

    These three only matter if you let the LLM write your shots. If you paste your own shot list, they change nothing for you.

    • Every story came out 15 shots. The system prompt ordered exactly 15 whenever the brief didn't ask for a count, so the model never got to decide. It now counts the story's beats and lands where the story lands — measured 4–7 on ordinary briefs, and about 7 when the brief gives no length signal at all. Seven chained shots is roughly 65 seconds at 243 frames, which clears the 1-minute mark platforms pay on. Ask for a specific count and you still get exactly that count.

    • The mode dropdown did nothing. The shipped workflow's system_prompt box held a frozen copy of the long-story prompt, and a filled box overrides the per-mode prompt file — so every mode ran the long prompt no matter what the dropdown said, and prompt updates in the pack never reached anyone using the shipped graph. The box now ships empty and the dropdown works. If you saved your own copy of the v2.0 or v2.1 workflow, clear that box by hand — your saved graph still carries the old frozen prompt, and this update cannot reach it. Related: short_story is now 1–3 shots instead of always exactly 1.

    • A messy answer from the model no longer kills the render. Three separate real failures, all seen on local models: a markdown fence sharing a line with the payload (```json {"prompts":…) was destroyed by the fence stripper; a reply truncated at the token ceiling left no balanced object to recover; and parsing sat outside the retry loop, so one malformed answer ended a run after a 100–240 s call that a re-ask usually fixes. The order is now clean → parse → retry ×3 → salvage the shots that completed → fail, and the final error names passthrough mode as the escape hatch.

    Verification, plainly. The reference lane, the per-shot saves and the --- fix are all confirmed by a live chained render, not by inspection: the console logs 2 reference image(s) ride in every shot as <Picture 1..2>, PASSTHROUGH: 4 shot(s) (it would have said 1 before the fix), and shot 1/4 saved through shot 4/4 saved, with four files on disk. The three JSON failures are unit-tested against the actual captured payloads that caused them; the live re-run afterwards parsed on the first attempt, so that proved no regression rather than proving the salvage path fires in a real queue. Shot counts were measured over two runs of five briefs on a local 8B: 4–7 shots, ±1 between runs — before the change all five returned 15. The custom sigmas input has not been exercised by a render — it needs a schedule source wired in, and I would rather say so than imply it.

    Install

    1. Unzip. Copy both node folders into ComfyUI/custom_nodes/:

      ComfyUI-H3-Multishot/            the sampler and helper nodes
      ComfyUI_JoyAI_Echo_GGUF_Nodes/   the LLM prompt writer (full workflow only)
    2. Restart ComfyUI. ComfyUI v0.30.0 or newer is required — that is the release with native MiniMax-H3 support.

    3. Load a workflow from workflows/ through the workflow menu.

    The full workflow needs five packs (two are in this zip): the writer pack below, ComfyUI-H3-Motion-Context for the context_pin default, RES4LYF for the beta57 scheduler, and ComfyUI-sol-attn + comfyui-minimax-h3-blockcache-T8 for the VRAM panel; ComfyUI-Custom-Scripts adds the script preview. ComfyUI validates every node class before it will queue, so a missing pack stops the whole workflow rather than just its own feature — INSTALL.md lists how to remove each one instead if you would rather not install it. CORE needs none of them, and that is tested on a clean install.

    On the Motion-Context fork. There is an active fork, ethanfel/ComfyUI-MiniMaxH3-Contex-Loop, well ahead of upstream with a disk-backed chain/loop system. It is a complement, not a replacement: by design it leaves the MiniMaxH3MotionContext node id to NikoDemon80's pack. Install the fork instead of upstream and context_pin still fails, because the node it calls is not there. Install both - they are built to coexist, and this pack works with either one's runtime patches. As of 2.1.1 the error message says so directly when it detects the fork.

    The writer pack is RealRebelAI's (github.com/RealRebelAI/ComfyUI_JoyAI_Echo_GGUF_Nodes), modified so the workflow's join rules actually reach the model; NOTICE_RIFT_MODIFICATIONS.md inside it lists every change. If you already have that pack, replace it with this copy. The CORE workflow does not need it at all.

    Models you need

    checkpoint    MiniMax-H3 ref2va     (GGUF Q8_0 / Q5_1 / Q4_0) -> models/diffusion_models
    text encoder  qwen3vl minimax_h3    (+ its -mmproj sidecar)   -> models/text_encoders
    video VAE     minimax_h3_video_vae                            -> models/vae
    audio VAE     minimax_h3_audio_vae                            -> models/vae

    GGUF quants: huggingface.co/joeygambino/MiniMax-H3-GGUF — Q8_0 for 32 GB, Q5_1 for 24 GB, Q4_0 below that.

    GGUF encoder pairing. ComfyUI-GGUF matches the -mmproj vision sidecar to the encoder by filename, in the encoder's own folder. Rename either, or split them up, and it loads the encoder without its vision tower — which presents as the model ignoring your reference image. This pack's CLIP loader raises instead of continuing blind, uses the only mmproj beside the encoder when there is exactly one, and takes an mmproj_name widget so you can point at the file directly.

    Which workflow

    • H3_Seamless_Chain_CORE — start here. The same seamless chaining with zero third-party packs. Type shots into the script box and queue.

    • H3_Seamless_Chain_v2 — everything: master controls, LLM writer, VRAM panel, identity and voice anchors, episode/batch prompt source, boundary plates, audio spine. Optional lanes are gated off by default.

    • H3_Keyframes — one clip, anchors at chosen frame positions, per-anchor condition strength.

    The two things that stop people on the first run

    1. The prompt writer needs a model you have pulled

    The full workflow points at a local Ollama with model_name = qwen3:14b. If it is not pulled, the first queue stops immediately:

    LLM API error 404: model 'qwen3:14b' not found

    Fix: ollama pull qwen3:14b. Any OpenAI-compatible endpoint works — its URL in base_url, its exact tag in model_name. ollama list prints the tags you have, and it must match character for character.

    No LLM at all? Set the master panel's use_file_prompts to manual entry, delete the writer, and feed your own script into the sampler's script input — one prompt per shot, separated by --- on its own line. CORE already works this way.

    2. A local writer will fight the video model for the card

    Turn on unload_model_after on the writer. It frees its own model from Ollama the moment the script is written. Without it the model stays resident for the server's default five minutes — your whole first shot. ComfyUI's own eviction cannot reach it, because Ollama is a separate process with its own allocator, and Ollama's OpenAI-compatible endpoint has no keep_alive field to ask with; the switch calls the native endpoint, which honours it. On under 32 GB, prefer a remote endpoint entirely.

    Settings: start here, change nothing

    checkpoint    ref2va          sampler     euler
    continuity    context_pin     scheduler   beta57  (full)  /  beta  (CORE)
    steps         14              fps         24
    frames/shot   362  (~15.1s, the trained maximum)
    resolution    1280x736 landscape   or   768x1344 vertical

    beta57 comes from RES4LYF, not stock ComfyUI. Measured on an identical seed it scored 10/10 for lip-sync against 8/10 for stock beta, with image quality, skin texture, artifacts and audio judged equal — so the full workflow ships it and lists RES4LYF as required, while CORE ships beta and keeps its zero-third-party-pack promise. One widget either way.

    Leave every VRAM switch off and the reserve at 0, and try a render before touching any of it. The activation reserve measures each shape and conditioning payload as it renders and sizes the pool itself; it holds on 24 GB cards as well as 32 GB. A hand-set reserve overrides that measurement, so a number that suited one shape becomes wrong for the next. Those switches exist to dig out of a spill the console has already named, not for pre-emptive tuning.

    Resolution cannot change mid-chain, and the mux must stay at 24 fps — other rates audibly shift voice accents. Dial-by-dial reference in SETTINGS.md.

    Writing a script that chains cleanly

    The previous shot's last ~1 second is replayed at the head of the next and discarded. Four rules follow, and breaking them is what produces mid-word chops and pose jumps:

    1. Open holding. Every shot after the first opens in the previous shot's exact closing arrangement, with no dialogue for ~2 seconds. Give it real micro-motion — a breath, a weight shift — so it does not read as a freeze.

    2. Land settled. Every shot ends with ~2 seconds of quiet, back in a stable arrangement, all dialogue finished.

    3. Never split a line across shots. Dialogue plus 4 seconds of hold and settle must fit the shot length. If it does not fit, move the whole line to the next shot.

    4. Repeat descriptions word-for-word. Character appearance and the room/light description, byte-identical in every shot. An unnamed light source gets reinvented per shot, and that is where colour drift starts.

    The LLM writer applies these for you. Hand-written scripts must follow them — PROMPTING.md has a worked four-shot example, and example_script.txt is ready to paste.

    How the chaining works

    context_pin carries the previous shot's last 22 frames as raw latents — never decoded to pixels and re-encoded — placed at interior keyframe coordinates, with a timeline-placed audio reference alongside. The regenerated head is trimmed on decode. Colour, motion and voice cross the boundary as data rather than as a description.

    Motion is the clearest case. Hand the next shot a single frame and it knows position but not velocity, so pace can reset at the boundary. Measured on a steady-pace walk: a single-frame anchor with no memory bank wobbled at the join; context_pin held it, and so did the memory bank on its own.

    first_frame is the alternative — the model's own trained hand-off, no extra pack, and what CORE ships with. cut for episodic work.

    Identity and voice

    • Nothing wired — the frame relay plus verbatim descriptions hold a face surprisingly well. A ~40 s two-character scene held both faces with no reference images at all.

    • self_anchor_voice (on) — shot 1's own rendered voice becomes the reference for every later shot. No file needed; write shot 1 with a clean solo line.

    • voice_ref — a clean solo speech clip, pinned across the whole chain including shot 1.

    • reference_images — character portraits carried into every shot as <Picture 1..N>. Bind them in the prompt text.

    • seed_per_shot (leave on) — measured: varying the seed per shot holds the face; one seed for every shot drifted both face and voice. Identity lives in the conditioning, not the seed.

    When something goes wrong

    • 404, model not found — the writer's model is not pulled. See above.

    • A word clips at a join — the script put dialogue too close to a boundary. Move the whole line; do not split it.

    • Sharpening increases every shot — the texture ratchet. Set chain_gain_control to flatten; worth it past about 5 shots.

    • Stalls at 0 steps, or runs several times slower than usual — a VRAM spill, the driver paging to system RAM instead of erroring. The console now names it. Raise the reserve, or drop resolution, frames, or reference payload.

    • Red or missing nodes — an optional pack is not installed. Delete those nodes, or use CORE.

    • GGUF architecture error — the pack teaches ComfyUI-GGUF the minimax_h3 architecture at startup. If it persists, run python apply_gguf_arch_patch.py from the pack folder once and restart.

    • Audio dulls on a very long chain — expected; restart the chain on a scene cut, where a fresh start costs nothing.

    Fixed in 2.1.1

    • context_pin died when ComfyUI-H3-Motion-Context was installed. Both packs patched the same ComfyUI method and Motion-Context refuses to stack on an unrecognised wrapper, so its payload patch failed and the chain errored. This pack's wrapper now does everything theirs does and declares their compatibility marker, so whichever loads first owns the site and the other stands down. Load order no longer matters. Verified with a live context_pin render.

    • seamless_tail crashed mid-chain with Motion-Context installed ("only first/last keyframe anchors are supported") - after your first shot had already rendered. It needs interior keyframe anchors, which conflict with that pack; it now stops before any sampling with the alternatives named: use context_pin, or first_frame, or remove that pack.

    • seamless often reads as a cut - now labeled. It is a legacy latent-only soft pin kept for comparison; the model satisfies it loosely. For a real join use context_pin or first_frame. The tooltip and settings reference now say so plainly.

    Why these never showed in testing here: an install-layout difference disabled the conflict detection on the dev machine. That detection is fixed, and release testing now runs on a packaged clean install so the class cannot slip through again.

    Everything you need is in the zip. One download: both node folders, all three workflows, and the full documentation. Nothing else to fetch, nobody to ask.

    What changed in 2.1

    • The full workflow now works on a clean install. It referenced a prompt-source node that had never been published, and drove the writer through inputs the upstream writer pack does not have — so the boundary rules never reached the model. It rendered, and it rendered worse than it should, with no error to explain why. Both fixed: that node ships here as RiftPromptSource, and the rules are written into the workflow's own system prompt as well as carried by the writer pack in this zip.

    • The chaining sampler's anchor switches now do something. voice_ref, reference_images, self_anchor_voice, preview_first_shot, two_pass_upscale, reference_image_size and the sampler/scheduler overrides were drawn on the canvas but absent from the class, so ComfyUI stripped them before execution. All real now, render-verified.

    • unload_model_after on the writer, described above.

    • SHOT COUNT on the master panel drives the sampler and the writer together so they cannot disagree; prompt source switches between a manual scene box and a prompt set, lazily.

    • Node titles no longer name a checkpoint or a switch position — a title like H3 model (fl2va) is a lie the moment you change the model.

    Two-pass upscale cannot be combined with context_pin or latent_handoff, or with an audio spine: those carry raw latents, or one locked denoise trajectory, across the join, and a two-pass render preserves neither. The node stops with an error naming the conflict rather than quietly producing a weaker join. Two-pass is available on cut, seamless, seamless_tail, first_frame and flf_chain.

    Credits

    Prompt writer: RealRebelAI (ComfyUI_JoyAI_Echo_GGUF_Nodes, modified — see the NOTICE in the zip). context_pin: NikoDemon80 (ComfyUI-H3-Motion-Context). Two-pass upscaling: Tr1dae (ComfyUI-MiniMaxH3_LatentUpscaler).

    FAQ

    Comments (39)

    snake88Aug 11, 2026· 1 reaction
    CivitAI

    the AIO script seems to be closer to what I want, the ref2a flexibility is really good and I trust it to preserve what I want at the seams more, the only thing lacking is sometimes tricky to get it to seamless transition instead of jump into slightly different positions.

    joeygambino
    Author
    Aug 11, 2026· 1 reaction

    Try latest v2.1 - seamless transitions built in by default.

    LemmingWolf01Aug 11, 2026· 1 reaction
    CivitAI

    Thank you for all the work you are putting into these workflows, it's appreciated.

    Unfortunately I'm have difficulty with v2.0 as I can't find JoyEcho_LLMEnhance or JoyEcho_PromptSource anywhere. Of course, they just so happen to support the feature I'm eager to try. Any pointers?

    Update1: I've installed JoyEcho_LLMEnhance from RealRebelAI's ComfyUI_JoyAI_Echo_GGUF_Nodes pack. Still looking for JoyEcho_PromptSource

    Update2: I had to drop joyecho_prompt_source.py from HF joeygambino/joyai-echo-multishot-workflow into custom_nodes\Comfyui_custom_scripts folder. I don't know if it's vital but I removed the second underscore in the file name as that was the name thrown by error in Comfyui.

    I think I'm ready to go, I'll leave this here in case it helps anyone else.

    joeygambino
    Author
    Aug 11, 2026

    v2.1 going up shortly to fix some bugs I didn't catch locally and will take care of this. Sorry!

    vladulidloAug 11, 2026
    CivitAI

    Both v2.0 and 2.1 do not seem to work with continuity=context_pin even with ComfyUI-H3-Motion-Context installed.

    [WARNING] h3_motion_context: another pack has already patched MiniMaxH3.extra_conds (it now comes from '/home/vlady/apps/ComfyUI/custom_nodes/ComfyUI-H3-Multishot.h3_avbank_probe'). Both packs are solving the same keyframe/ref collision and they cannot both own it, so this one is refusing. Disable one of them and restart.

    [ERROR] !!! Exception during processing !!! h3_motion_context: the payload patch could not be applied. Without it the audio ref would overwrite the pinned video latents and the motion context would be lost. The reason was logged just above this error.

    vladulidloAug 11, 2026

    A different issues found:
    continuity=seamless behaves as a cut, not seamless at all.

    continuity=seamless_tail errors out with T2V mode AFTER sampling, not before:
    [ERROR] !!! Exception during processing !!! only first/last keyframe anchors are supported

    I'm in search of seamless T2V (and I2V) clip chaining and could not find working setting in the current version. Both identity anchor gate [OFF] and FFLF PLATES gate [OFF - flf_chain only] are set to T2V

    joeygambino
    Author
    Aug 11, 2026· 1 reaction

    @vladulidlo All three confirmed, and thank you - this is an excellent report. 2.1.1 is up with the fixes.

    context_pin + Motion-Context: my pack was grabbing the same patch site Motion-Context needs, before their pack could. Their code publishes a compatibility marker for exactly this situation; mine now honours it, so the two coexist and load order no longer matters. Verified with a live context_pin render.

    seamless_tail: real conflict - it needs interior keyframe anchors, which collide with Motion-Context's ownership of that patch math. It now stops before sampling with a clear message instead of dying after your first shot. With Motion-Context installed, use context_pin - it's the stronger mechanism and what that pack is for.

    seamless: you're right, and the tooltip now says so - it's a legacy latent-only soft pin kept for comparison, and it often reads as a cut. For seamless T2V chaining use context_pin (or first_frame on an fl2va checkpoint). Both are the measured, working paths.

    The bug never showed on my machine because of an install-layout difference that disabled the conflict detection - also fixed, and my release testing now runs on a packaged clean install so this class doesn't slip through again.

    vladulidloAug 11, 2026

    @joeygambino 

    Thank you! For both the fixing and fixing it so quickly!

    Emanresu_ymAug 11, 2026· 1 reaction
    CivitAI

    Seems like the bugs started eating into the bugs, chill, don't rush, take your time, customers can wait.

    joeygambino
    Author
    Aug 11, 2026

    Ha, thanks. I do tend to rush when I have a new feature to show off. A lot of bugs don't pop up until someone reports them, because the workflows are functioning perfectly for me, but then I realize the things other people just don't have installed.

    Emanresu_ymAug 11, 2026· 1 reaction

    @joeygambino yeah people are too excited for new model and what they can do. also samples looks good, compared to previous degrading over time was visible, now it looks stable through all 30 secs. will be trying lastest WF later on, good job!

    vladulidloAug 11, 2026· 1 reaction
    CivitAI

    I would like to point to a fork https://github.com/ethanfel/ComfyUI-MiniMaxH3-Contex-Loop

    ethanfel's fork is 51 comits ahead of original https://github.com/NikoDemon80/ComfyUI-H3-Motion-Context, but also not (yet) compatible with ComfyUI-H3-Multishot.

    So if you are seeing:

    RuntimeError: continuity=context_pin needs the ComfyUI-H3-Motion-Context pack installed (github.com/NikoDemon80/ComfyUI-H3-Motion-Context)

    You could have downloaded the fork instead of https://github.com/NikoDemon80/ComfyUI-H3-Motion-Context

    joeygambino
    Author
    Aug 11, 2026· 1 reaction

    Thank you - you're right, and I've verified it against the fork's source. It registers 18 node ids (MiniMaxH3LoopTrim, the MiniMaxH3Chain* family, the Scheduled* reference nodes) and deliberately does not re-register MiniMaxH3MotionContext. From its own init.py: "The original Motion Context, Save Latent, and Load Latent ids remain exclusively owned by Niko's upstream pack."

    So, the fork is a complement rather than a replacement - install both. They're built to coexist, and this pack works with one's runtime patches because all three honor the same patch-ownership markers.

    My error message was unhelpful about that, so 2.1.1 now detects the fork and says exactly this instead of just naming a repo you thought you'd installed. It's also documented in INSTALL.md.

    That fork looks well worth a look on its own merits, by the way, a disk-backed chain/loop system with review gates and checkpoint resume is solving a different problem than this pack and solving it further than I have.

    vladulidloAug 11, 2026

    @joeygambino Good to know! I'm glad you find the forked repo interesting as I do.

    ProfugoBarbatusAug 11, 2026· 3 reactions
    CivitAI

    Just installed 1.5 last night, after wondering to myself "This new H3 stuff is amazing, just wish I could load more than start/stop keyframes" and looking at civitai for a lark. Blown away by this stuff - once 2.0 or its successors settle out from the bugs, I'll update, but this is already incredible, bordering on revolutionary for me to mess around with. Well done!

    joeygambino
    Author
    Aug 11, 2026

    Thank you! 2.1.1 should mostly be bug free now - but if you find anything, I try to be quick about fixing things. Sometimes stuff that works perfectly on my machines, don't necessarily work well on others due to different Comfy versions, hardware, node packs installed, etc. I don't know something is broken until someone tells me.

    Emanresu_ymAug 11, 2026· 2 reactions
    CivitAI

    I have noticed that this larryvrh/MiniMax-H3-Turbo-Lora is not burning the output like the lightning one does, anyone else been using it with this workflow?

    joeygambino
    Author
    Aug 11, 2026

    The only one I've used so far is minimax_h3_turbo_4step_ckpt500.safetensors

    And I can't even say I've tested it enough to know it works. When I did test it, it didn't seem to work very well with my workflows unless it was at 12 steps + only Euler - which at the time it was in Alpha so I didn't bother testing further and figure people will use their own anyway. I didn't realize he'd put a hundred more options up though, so I may have to give them a shot.

    I've tried to optimize things enough so you don't need a lightning/turbo lora, and 4 steps on a video render seems nuts to me, but I suppose I should give it a shot.

    Emanresu_ymAug 11, 2026· 1 reaction

    @joeygambino with latest V4 he even says 4 steps is not enough need to be minimum 6-8, at 8 no improvement would be gained. he also uses custom sampler and custom lora loader for those who has less Vram.

    audrymax919Aug 11, 2026· 2 reactions
    CivitAI

    Thanks for all the work on this pack, the chaining is genuinely great.

    Found a bug though: guide_audio (Audio Spine) with a real voice track outputs static/hiss instead of the audio, on ref2va. Same audio file works perfectly through the native MiniMaxH3ReferenceToVideo node, so it seems isolated to the Audio Spine injection path

    joeygambino
    Author
    Aug 11, 2026

    On it, next update, coming tonight.

    audrymax919Aug 12, 2026

    @joeygambino Thanks for the reply! Quick update: I've now tested up through 2.1.6, same result.

    The resample fix from 2.1.3 is confirmed working on my end (console shows the resample happening correctly), but the audio is still coming out as static/garbled, no change from before the fix.

    I've ruled out continuity mode (context_pin/latent_handoff), checkpoint format (safetensors and GGUF), scheduler (beta/beta57), and LoRA, same result every time. voice_ref works perfectly on the exact same file, so it's specifically the guide_audio path that's still broken for me.

    How are you testing this on your end? Trying to figure out what's different about my setup (RTX 5090, ComfyUI 0.32.0).

    joeygambino
    Author
    Aug 12, 2026

    Got it — and the answer to "how are you testing this on your end" is the bug. I am on ComfyUI 0.30.0. You are on 0.32.0. It works here and cannot work there, and that is entirely on me for not testing across versions.

    What changed. 0.32.0 introduced ModelSamplingAV, and ComfyUI now carries the audio half of the audio+video pack scaled onto the video schedule:

    process_latent_in audio slice x (shift / audio_shift)

    process_latent_out audio slice x 1 / (shift / audio_shift)

    For H3 those shifts are 12 and 3, so the audio latent inside the sampler lives in a 4x-scaled domain. The Audio Spine locks its encoded audio into that pack during sampling — and it was writing raw, unscaled values. Every locked column lands 4x too small, which decodes as exactly the static you are hearing. On 0.30.0 there is no such scaling, so raw was correct.

    That accounts for everything you found, and your process is what made it findable:

    - voice_ref works on the same file — it goes through the text conditioning and never touches the sampler's latent, so the scaling never applies to it.

    - The 2.1.3 resample fix fires and changes nothing — you were right, it works. Encoding was never the problem; the problem is one step later.

    - Continuity mode, checkpoint format, scheduler, LoRA all irrelevant — none of them touch this path. Ruling them out is what pointed at the sampler.

    Also worth knowing: *audio_lock has the identical bug** on 0.32.0, same code path, same cause. It is fixed by the same change.

    The fix reads the scale off the live model_sampling object rather than hardcoding 4, so it stays correct if you change the shifts with MiniMaxH3SigmaShift, and it leaves 0.30.0 behaviour byte-identical. It is written and deployed on my side but I have not render-verified it on 0.32.0 yet - I am setting up a 0.32.0 instance to reproduce your exact failure and confirm the cure rather than ship it on code reading alone. It will be in the next release, which is close.

    Until then, honestly, there is no clean workaround. voice_ref will hold one voice across shots and is the nearest thing, but it is not the spine — it does not lock every shot to one continuous performance. If you need the spine specifically, 0.30.0 is the only place it currently works, and I would not recommend downgrading a whole install for one feature when the fix is coming.

    Thank you for staying with this through 2.1.6 and for testing so carefully. Four ruled-out variables plus "voice_ref works on the same file" is what turned this from a shrug into a one-line fix.

    joeygambino
    Author
    Aug 12, 2026

    Oh, and, sorry about "coming tonight" - I got sidetracked trying to add too many features at once, which I tend to do. I am going to say it again though... fix is coming tonight (I hope).

    audrymax919Aug 12, 2026

    Thanks for the deep dive, really appreciate it! No worries about the delay, I'll wait for the fix and try guide_audio again once it's out

    egin1992654Aug 11, 2026
    CivitAI

    attention (gated) and chunk (gated) nodes dont work for me

    joeygambino
    Author
    Aug 11, 2026

    Can you paste the errors from the terminal?

    egin1992654Aug 12, 2026

    @joeygambino [WARNING] invalid prompt: {'type': 'missing_node_type', 'message': "Node 'attention patch (gated)' has no class_type. The workflow may be corrupted or a custom node is missing.", 'details': "Node ID '#9'", 'extra_info': {'node_id': '9', 'class_type': None, 'node_title': 'attention patch (gated)'}}

    egin1992654Aug 12, 2026

    @joeygambino also in multishot wflow now have error
    Prompt outputs failed validation: H3MultishotMemorySampler: - Value 4 bigger than max of 3: memory_frames

    Это может быть связано со следующим скриптом:
    /extensions/comfyui-easy-use/assets/extensions-WrZZZUnM.js

    joeygambino
    Author
    Aug 14, 2026

    @egin1992654 Sorry for the late response, I missed you replied.

    ## 1. The gated nodes: two packs to install

    The full workflow uses three nodes from two packs I am not allowed to bundle.

    I shipped them switched off, assuming that was enough - it is not.

    ComfyUI checks that every node class exists before it will queue anything, even a node that is switched off, so a missing pack stops the whole workflow instead of just that one feature.

    Install these two and the workflow runs exactly as shipped:

    ComfyUI-sol-attn (provides two of the three)

    https://github.com/Saganaki22/ComfyUI-sol-attn

    comfyui-minimax-h3-blockcache-T8 (provides the third)

    https://github.com/T8mars/comfyui-minimax-h3-blockcache-T8

    Via ComfyUI Manager (easiest): Manager > Install via Git URL, paste each URL in turn, then restart ComfyUI.

    Or by hand:

    cd ComfyUI/custom_nodes

    git clone https://github.com/Saganaki22/ComfyUI-sol-attn

    git clone https://github.com/T8mars/comfyui-minimax-h3-blockcache-T8

    then restart ComfyUI. Check the console on startup - if either pack fails to import it will say so there, and that message is the thing to send me.

    Reload the workflow afterwards. The three nodes will resolve, and the error goes away. They are speed and memory optimisations, so you will also get a faster render out of it.

    One thing worth knowing: those three ship bypassed on the canvas. Installing the packs stops the error. If you then want the speed as well, select each node and press Ctrl+B to un-bypass it, and turn on the matching switch on the FEATURE SWITCHES panel. Leaving them bypassed is fine too - everything renders identically, just slower.

    ## 2. The memory_frames error

    Value 4 bigger than max of 3 - that dial only accepts 0 to 3.

    Open the H3MultishotMemorySampler node and set memory_frames to 0 (that is the shipped default), then queue again.

    If other dials on that node also look wrong, the workflow file you loaded was saved by an older release. The sampler gained widgets over several versions, and when a saved file has a different number of values than the node has dials,

    ComfyUI fills them in order and everything after the mismatch lands on the wrong dial. In that case load H3_Seamless_Chain_v2.json fresh out of the current zip rather than reusing your saved copy - then re-enter any settings you had changed.

    drowai443Aug 11, 2026· 2 reactions
    CivitAI

    You're definitely getting there, man. This is good stuff.

    Your own video above has a cut and isn't seamless though. And the image degradation is pretty severe by the end, like WAN 2.2. Seems like you did fix color shift and audio, and there are no overbright frames at the seams, so this is insane progress for only a few days.

    Keep up the great work.

    joeygambino
    Author
    Aug 12, 2026· 3 reactions

    Yeah, I am working on the degradation, expecting to have some progress by morning. The cut.. I don't even know what happened there, it's been pretty steadily working for me.

    wallmonster151Aug 12, 2026
    CivitAI

    Hey, first as almost everyone else has already said. Thanks for your amazing work! And also for being so engaged on follow ups!

    I managed to get your Riftcast Studio up and running the other day. This flow was looking like a seamless startup for me after I got rid of a Fantasy Talking GGUF node conflict. Then unfortunately the flow ran to about 85% before throwing a math error. I believe I had everything in place as the models auto-populated when I loaded the H3_Seamless_Chain_v2 flow. This was just with the stock images and prompts.

    H3 Multishot Sampler + Memory (long form)

    Error log

    # ComfyUI Error Report ## Error Details - Node ID: 30 - Node Type: H3MultishotMemorySampler - Exception Type: RuntimeError - Exception Message: RuntimeError: mat1 and mat2 shapes cannot be multiplied (3680x1152 and 3456x1152)

    I ran the update patch and it came back success. Apologies if this is one of those long since asked and answered. Feel like I had a pretty solid look around for someone with the same issue and cam up empty.

    Thanks


    LemmingWolf01Aug 12, 2026

    @joeygambino Hi, just to add a little more to this as I've been having the same error. My settings in the master control are 640x960 (2:3) I'm only using one image, or at least it's the only one activated and that's in the Identity Anchor Image Node and the resolution is 1024x1536 (2:3) so from a resolution perspective they should be compatible?

    The things I have noticed:

    1. It only errors if I'm using a GGUF text encoder, safetensors work fine although it doesn't bring the image in as the first image for the shot.

    2. After the error if I look at the parameters for the node, which I assume reflect the state of play when the fatal error occurred, width and height are reported as 764x1344 which isn't 2:3. However, if I do get a successful run (using a safetensor text encoder) the finished video is as specified in the master control i.e. 640x960.

    I don't know what any of this means, it's mostly all well above my brain cell count, but I thought I'd let you know incase it helps.

    Edit: Just to mention after reading wallmonster's latest comments, my error occurs pretty much as soon as it hits the sampler.

    wallmonster151Aug 12, 2026

    @joeygambino Thanks for the quick response!

    Should have clarified but as with Lemming below that was with the gguf models. That first run was with only the place holder 768x768 images in there slots. All use image toggles were turned off which should have defaulted to whatever T2I resolution the workflow was saved at and the example text in place. I do not believe I flipped a single toggle on that run. When I was first starting with comfy I threw a lot of math errors with text encoder mismatches but as you said those where always when the first merge happened. Here it goes pretty much all the way until it is getting ready to move off the ksampler. Rough previews were generating that looked to match your example script. Maybe trying to merge the shots?.

    Anyway I'll keep digging through my settings. I do have a pretty robust local machine so I'll give the safetensors version a try. My main interest in gguf version is iteration speed as I am learning, as we see here it is sometimes better to fail fast. Local storage space is another big plus for gguf. Like most of your users I am a bit of a hoarder and hesitant to delete anything. Either I have happy memories of one good run with that file or it is on my mental list to go back and figure out how to optimize later.

    Edit here: It was not actually at 85%. The ksampler goes to 100% of the first shot and the error throws on the handoff to the second shot. I made sure the image input toggles were all turned off and for extra security bypassed all of their loaders as well as the audio anchor loader. I tried 1152x1152 hoping for a direct match to the model but something, somewhere is adding a little to the image width no matter what I put in the master. I changed the reference image size toggle from match to max also with no joy.

    Edit 2: I thought I kept everything 100% unchanged when I first loaded the workflow but I may have been a little too proactive. When trying to figure out where the extra width is coming from I changed the text encoder sidecar setting from referencing the actual file to auto and at least T2V it was able to join 2 shots and run to completion. It's certainly possible that I populated that field myself on the initial run. Testing I2V now with the sidecar on auto.

    Edit 3: It runs to completion I2V with the sidecar set to auto.

    Early days after only one run but the initial run off of the same reference image and resolution did not seem to generate the same quality as your Riftcast/JoyEcho workflows. Now that I have completed a run I'll move up to the Q8 model and see how that goes.

    Thanks again!

    joeygambino
    Author
    Aug 12, 2026

    Found it - and it is my bug, not your setup. Ignore my earlier answer about resolutions; that was wrong, sorry for the detour.

    It's the mmproj_name widget on the H3 CLIP Loader. Naming a file there went down a different code path than (auto) and skipped the key-renaming step, so the vision tower loaded under names nothing reads. That is why it always died at the shot-2 handoff, why it was GGUF-only, and why nothing you changed about resolution or image toggles helped.

    Manual fix, in order of least effort:

    1. Set mmproj_name back to (auto). If it loads, you are done.

    2. If (auto) then says "No vision sidecar resolved", the pairing is by filename - the mmproj must sit in the same folder as the encoder and contain the encoder's name minus its quant suffix:

    So either rename the mmproj to match, or make it the only file with "mmproj" in the name in that folder - the loader falls back to "if there is exactly one, use it."

    3. If you would rather not touch your model folder, one line in custom_nodes/ComfyUI-H3-Multishot/h3_multishot_utils.py. Find:

    if mmproj_name and mmproj_name != "(auto)":

    and change it to:

    if False and mmproj_name and mmproj_name != "(auto)":

    That makes the widget inert and forces the working path. Restart ComfyUI. It is a workaround, not the fix - the real one keeps the widget working for people with split folders.

    Or just wait. It is already fixed and verified on my side, and the next release is close — it also carries two other things that stop the workflow running for anyone who installed from here: the accelerator nodes shipped switched on (so a clean install could not queue at all), and a widget mismatch that threw "The value 1 for reference_image_size is not available". If you are not blocked today, the update will be the cleaner path.

    Thanks again - @wallmonster151, your Edit 2 is what found this. It would have stayed hidden for a long time otherwise.

    @LemmingWolf01 - the 768x1344 you saw on the node after the error is a display quirk, not the cause: width and height are driven by links from MASTER CONTROLS, so the widget keeps showing its own stored default. Your render really was 640x960. Separately, tell me which safetensors encoder you used when the image did not come in as the first frame and I will chase that one too.

    joeygambino
    Author
    Aug 12, 2026

    Found it - and it is my bug, not your setup. Ignore my earlier answer about resolutions; that was wrong and I am sorry for the detour.

    It is the mmproj_name widget on the H3 CLIP Loader. Naming a file there went down a different code path than (auto) and skipped the key-renaming step, so the vision tower loaded under names nothing reads. That is why it always died at the shot-2 handoff, why it was GGUF-only, and why nothing you changed about resolution or image toggles helped.

    Manual fix, in order of least effort:

    1. Set mmproj_name back to (auto). If it loads, you are done.

    2. If (auto) then says "No vision sidecar resolved", the pairing is by filename - the mmproj must sit in the same folder as the encoder and contain the encoder's name minus its quant suffix:

    MiniMax-H3-encoder-Q5_K_M.gguf + MiniMax-H3-encoder-mmproj-F16.gguf pairs

    MiniMax-H3-encoder-Q5_K_M.gguf + mmproj-F16.gguf does not

    So either rename the mmproj to match, or make it the only file with "mmproj" in the name in that folder - the loader falls back to "if there is exactly one, use it."

    3. If you would rather not touch your model folder, one line in custom_nodes/ComfyUI-H3-Multishot/h3_multishot_utils.py. Find:

    if mmproj_name and mmproj_name != "(auto)":

    and change it to:

    if False and mmproj_name and mmproj_name != "(auto)":

    That makes the widget inert and forces the working path. Restart ComfyUI. It is a workaround, not the fix - the real one keeps the widget working for people with split folders.

    Or just wait. It is already fixed and verified on my side, and the next release is close — it also carries two other things that stop the workflow running for anyone who installed from here: the accelerator nodes shipped switched on (so a clean install could not queue at all), and a widget mismatch that threw "The value 1 for reference_image_size is not available". If you are not blocked today, the update will be the cleaner path.

    Thanks again - @wallmonster151, your Edit 2 is what found this. It would have stayed hidden for a long time otherwise.

    @LemmingWolf01 - the 768x1344 you saw on the node after the error is a display quirk, not the cause: width and height are driven by links from MASTER CONTROLS, so the widget keeps showing its own stored default. Your render really was 640x960. Separately, tell me which safetensors encoder you used when the image did not come in as the first frame and I will chase that one too.

    wallmonster151Aug 12, 2026

    @joeygambino Thanks man! Coincidentally I saw you were updating that file on git when I was digging around. I almost threw in the new utils file to test. I will do that on the next run. In truth I spent a fair amount of time hacking around in that file last night with no joy so I did a full revert to confirm the issue before reaching out.

    LemmingWolf01Aug 13, 2026

    @joeygambino Hi, thanks for the updates and I can confirm that GGUF text encoders work now. With regard to the first frame issue, the safetensors encoder I was using was just the stock "qwen3vl_32b_minimax_h3_nvfp4_awq" I've since tried with a GGUF + mmproj and still no first frame from my Identify anchor image. Perhaps I'm not fully understanding the process and it's something I'm doing wrong. As it stands I have the:

    Reference Gate OFF,

    FFLF Plate Gate OFF,

    Identity Anchor gate ON (with image),

    Continuity = first_frame,

    and using a fl2va model (I have tried a ref2va model as well, though in this instance it shouldn't be required, should it?)

    As I understand things, that should produce a shot with the first frame as per my Identity Anchor image.

    As I said, maybe it's something I'm doing or not doing.

    Thanks for all your fantastic work and help.

    Workflows
    MiniMax H3

    Details

    Downloads
    423
    Platform
    CivitAI
    Platform Status
    Available
    Created
    8/11/2026
    Updated
    8/16/2026
    Deleted
    -

    Files

    minimaxH3MultishotSeamlessChain_v212.zip