Comfy-Org/ComfyUI · error · ValueError
The connected model_patch is not an LTX duration head.
Error message
The connected model_patch is not an LTX duration head.
What it means
Raised by the LTX duration-prediction node's execute(): it takes the model_patch-style input 'duration_head' and checks isinstance(head, comfy.ldm.lightricks.duration_head.DurationHead). Any other model-patch object (ControlNet, LoRA hook, IP-Adapter patch, plain ModelPatch) fails the check because the node needs the DurationHead module to run the caption connectors exactly as sampling does.
Source
Thrown at comfy_extras/nodes_lt.py:1153
io.Conditioning.Input("positive"),
io.Custom("MODEL_PATCH").Input("duration_head",
tooltip="LTX 2.4 duration head loaded with ModelPatchLoader."),
io.Float.Input("frame_rate", default=24.0, min=1.0, max=120.0, step=0.01),
io.Float.Input("min_seconds", default=1.0, min=0.5, max=120.0, step=0.1),
io.Float.Input("max_seconds", default=20.0, min=0.5, max=120.0, step=0.1),
],
outputs=[
io.Int.Output(display_name="num_frames"),
io.Float.Output(display_name="seconds", tooltip="Raw (unclamped) predicted duration."),
],
)
@classmethod
def execute(cls, model, positive, duration_head, frame_rate, min_seconds, max_seconds) -> io.NodeOutput:
dm = model.model.diffusion_model
head = duration_head.model
if not isinstance(head, comfy.ldm.lightricks.duration_head.DurationHead):
raise ValueError("The connected model_patch is not an LTX duration head.")
context = positive[0][0]
meta = positive[0][1]
if context.shape[0] != 1:
context = context[:1]
# Run the caption connectors exactly the way sampling does.
comfy.model_management.load_models_gpu([model, duration_head])
device = model.load_device
head = head.to(device)
with torch.no_grad():
context = context.to(device=device, dtype=model.model.get_dtype_inference())
processed = dm.preprocess_text_embeds(context, unprocessed=meta.get("unprocessed_ltxav_embeds", False))
video_tokens = processed[..., :dm.cross_attention_dim].float()
audio_tokens = processed[..., dm.cross_attention_dim:].float()
seconds = float(head(video_tokens, audio_tokens)[0])
num_frames = comfy.ldm.lightricks.duration_head.seconds_to_num_frames(View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Connect the output of the dedicated LTX duration-head loader node (the one that yields a DurationHead-backed model patch) into duration_head.
- Remove any intermediate patch-application nodes between the loader and this input.
- Verify visually that duration_head is not fed by a ControlNet/LoRA loader.
Defensive patterns
Strategy: type-guard
Validate before calling
import comfy.ldm.lightricks.duration_head as dh
assert isinstance(duration_head.model, dh.DurationHead), (
"duration_head input must come from the LTX duration-head loader, not a generic model patch") Type guard
def is_ltx_duration_head(model_patch) -> bool:
import comfy.ldm.lightricks.duration_head as dh
return isinstance(getattr(model_patch, "model", None), dh.DurationHead) Prevention
- Only connect the dedicated LTX duration-head loader output to this input.
- Never route ControlNet/LoRA/patch-apply outputs into duration_head.
- Name-check the loader node when building the workflow template.
When it happens
Trigger: Connecting the output of a generic LoadPatch or a ControlNet/LoRA loader into the duration_head input; connecting a ModelPatchDXL-style wrapper whose .model is not a DurationHead; forgetting the dedicated LTX duration-head loader node.
Common situations: Building the LTX-2 duration workflow and grabbing the wrong loader node from the menu; reusing a template where the patch slot was rewired.
Related errors
- DurationHead requires at least one of video_tokens / audio_t
- This Controlnet needs a VAE but none was provided, please us
- Need at least {require_count} hooks to combine, but only had
- Unsupported spatial_scale {scale}. Choose from {list(mapping
- Either spatial_upsample or temporal_upsample must be True
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/f7b79526c88fcc86.
Report an issue: GitHub.