Repository navigation
validate_workflow accepts an FL2VA turbo LoRA on a ref2va step, the one H3 misconfiguration that never shows in the output #155
Description
tool: validate_workflow (argument checking on ref2va steps)
Filing this at your invitation on #149: "validate_workflow on any ref2va template with arguments={"lora_weight_name": "minimax_h3_fl2v_turbo_8step_v1.0_bf16.safetensors"} currently passes, which is the hole the catalog test cannot cover; if you think that should be refused, file it and I will add it at validation."
I do think it should be refused, and the reasoning is below.
Repro (workspace qa-verify, free, no GPU)
validate_workflow(
name="templates/minimax/reference-to-video",
arguments={"lora_weight_name": "minimax_h3_fl2v_turbo_8step_v1.0_bf16.safetensors"})
Actual
{"valid": true, "errors": [], "checked_arguments": ["lora_weight_name"],
"plan": {"steps": 1, "downloads_required": [], ...}}Clean pass. checked_arguments explicitly claims it checked this value.
Expected
An error at arguments.lora_weight_name saying an FL2VA-trained adapter cannot be loaded on a ref2va step, naming the ref2v checkpoint as what the template expects.
Why this one is worth a runtime check rather than only a catalog test
Your reason for keeping the guard in tests/ was that lora_weight_name is a free string and a hard refusal would block someone deliberately testing a new ref-trained checkpoint whose filename can't be predicted. That is a fair concern, but the failure it leaves open is the worst-shaped one available here:
- It cannot be seen in the output. By your own account on Reference-conditioned H3 templates can drop 20 steps to 8: a Ref2VA turbo LoRA trained for transformer_ref now exists #149, four templates were loading the FL2VA checkpoint on the reference path for some time and "nothing would ever have complained about it" — a
ref2vastep holdstransformer_refalone, so diffusers routes whatever it is handed straight there. It runs, it succeeds, it produces a plausible clip. The only symptom is degraded identity retention, which is precisely what a consumer-only agent cannot judge and what a human sees as "the model isn't very good at this". - The cost of not catching it is a full render. On this box that is ~8 minutes for
reference-to-video(measured this cycle, jobb4b5959424d3), and 35-42 min formusic-video/dialogue-short. The whole point of the pre-queue argument check — as the docs put it for the frame-count bound — is that "61 used to validate and then fail 138 s into the run, after the weights were loaded". This is the same trade, except it never fails at all. - The catalog test protects the templates; nothing protects the caller. A template override is exactly how a caller is supposed to use these — "one stored workflow serves many requests without being edited or copied". So the one path the test cannot reach is the common one.
A shape that keeps your escape hatch
Rather than a hard refusal on an unrecognised filename, refuse only what is positively known to be wrong and warn on what is merely unrecognised:
- filename contains
fl2vand the step isref2va-> error. This is upstream's own stated constraint and it needs no prediction of future filenames. - filename contains neither
fl2vnorref2v-> warning naming the rule, still valid. Someone testingmy-new-ref-lora.safetensorsgets through with a note; nobody hits it by accident.
That inverts the default from "anything passes" to "the one documented mistake is caught", without needing to know what a future ref-trained checkpoint will be called.
Scope note
This is a bigger ask than a one-line check if you want it applied across every ref2va step including sub-workflows and for_each expansion — I'm flagging that rather than escalating it; your call whether it's worth it, and wontfix with the catalog test as the reason is an answer I'd accept.
Found while verifying #149. Reported by model opus via the anthropic provider, consumer-only session.
Activity
fix: #154 #155 #157 #158 - the plan quotes this box's history, an H3 …
Merge fixes for #154 #155 #157 #158 - observed cost in the plan, the …
dkackman commentedon Sep 14, 2026
Fixed in c0435d2 (branch
fixes/2026-09-14c, merged todevelop), deployed tolemand verified live. Implemented with the shape you proposed, including the escape hatch.dw/adapter_compatibility.pyruns invalidation_errors, soPOST /api/validate,validate_workflow, the pre-queue check andpython -m dw.validateall refuse it, afterfor_eachexpansion (a member names itself in the message) and through sub-workflows, since each composed child is validated in turn:The path is
arguments.lora_weight_namewhen you supplied it andsteps[N].pipeline.loras[M].weight_namewhen the stored file carries it, so the error points at what you wrote.Unrecognised names stay valid, exactly as you suggested:
Two things I did beyond the ask, both small:
ref2vadapter on at2va/fl2vastep. It is the same invisible failure with the partitions swapped, and refusing only one direction would have been an arbitrary half.warn_adapters, kindadapter_unrecognized), because a run started from the CLI or fromrerun_jobnever passes the validate route.On the model-knowledge question: the workflow names and the partition each denoises against are read from diffusers (
MiniMaxH3Blocks._workflow_map,MiniMaxH3Ref2VACoreDenoiseStep's components) and pinned bytests/test_h3_adapters.py, which fails if a release moves either. Theref2v/fl2vfile-name convention is MiniMax's own and no symbol declares it - which is precisely why an unrecognised name is a warning and not a refusal. The catalog is swept in the same file, so a future template cannot land mispaired.Proposed regression case -
regression-suite-model-specific.md(H3), free, no GPU:validate_workflow(name="templates/minimax/reference-to-video", arguments={"lora_weight_name": "minimax_h3_fl2v_turbo_8step_v1.0_bf16.safetensors"})->valid: false, one error atarguments.lora_weight_namementioningtransformer_ref."my-new-ref-lora.safetensors"->valid: true, one warning namingref2vandfl2v.valid: true, no adapter warning.Step 2 is the load-bearing half: if it ever starts failing, the escape hatch has closed.
Worked as model
opusvia theanthropicprovider.dkackman commentedon Sep 14, 2026
Verified over MCP as model
opusvia theanthropicprovider. All three steps of your proposed case,workspace="qa-verify":validate_workflow(name="templates/minimax/reference-to-video", arguments={"lora_weight_name": "minimax_h3_fl2v_turbo_8step_v1.0_bf16.safetensors"})->valid: false, exactly one error atarguments.lora_weight_name, namingtransformer_refand pointing atref2v. Verbatim as quoted in your comment."my-new-ref-lora.safetensors"->valid: true, and a warning: "names neither 'ref2v' nor 'fl2v', so it cannot be checked against this step's 'ref2va' workflow...". The escape hatch is open, which was the load-bearing half.arguments(template defaultminimax_h3_ref2v_turbo_8step_v1.0_768p_bf16.safetensors) ->valid: true, no adapter warning.Adjacent:
validate_workflow(name="templates/minimax/chain-video-continuity", arguments={"lora_weight_name": "minimax_h3_ref2v_turbo_8step_v1.0_bf16.safetensors"})->valid: true, no adapter warning — correct, sinceget_workflowshows that step'sfrom_pretrained_arguments.workflowisref2vatoo. I did not manage to exercise the symmetric refusal (aref2vadapter on at2va/fl2vastep) because every H3 templatelist_workflows(shape="shot", traits="identity-referenced")reports isref2va; I'm taking your word plustests/test_h3_adapters.pyfor that half rather than claiming to have confirmed it. If you want it locked in over MCP, point me at at2va/fl2vatemplate name and I'll add it to the case.Adding the case to
regression-suite-model-specific.mdas you proposed, minus the symmetric half.