{"record":{"id":"f7b79526c88fcc86","repo":"Comfy-Org/ComfyUI","slug":"the-connected-model-patch-is-not-an-ltx-duration-h","errorCode":null,"errorMessage":"The connected model_patch is not an LTX duration head.","messagePattern":"The connected model_patch is not an LTX duration head\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_extras/nodes_lt.py","lineNumber":1153,"sourceCode":"                io.Conditioning.Input(\"positive\"),\n                io.Custom(\"MODEL_PATCH\").Input(\"duration_head\",\n                                               tooltip=\"LTX 2.4 duration head loaded with ModelPatchLoader.\"),\n                io.Float.Input(\"frame_rate\", default=24.0, min=1.0, max=120.0, step=0.01),\n                io.Float.Input(\"min_seconds\", default=1.0, min=0.5, max=120.0, step=0.1),\n                io.Float.Input(\"max_seconds\", default=20.0, min=0.5, max=120.0, step=0.1),\n            ],\n            outputs=[\n                io.Int.Output(display_name=\"num_frames\"),\n                io.Float.Output(display_name=\"seconds\", tooltip=\"Raw (unclamped) predicted duration.\"),\n            ],\n        )\n\n    @classmethod\n    def execute(cls, model, positive, duration_head, frame_rate, min_seconds, max_seconds) -> io.NodeOutput:\n        dm = model.model.diffusion_model\n        head = duration_head.model\n        if not isinstance(head, comfy.ldm.lightricks.duration_head.DurationHead):\n            raise ValueError(\"The connected model_patch is not an LTX duration head.\")\n\n        context = positive[0][0]\n        meta = positive[0][1]\n        if context.shape[0] != 1:\n            context = context[:1]\n\n        # Run the caption connectors exactly the way sampling does.\n        comfy.model_management.load_models_gpu([model, duration_head])\n        device = model.load_device\n        head = head.to(device)\n        with torch.no_grad():\n            context = context.to(device=device, dtype=model.model.get_dtype_inference())\n            processed = dm.preprocess_text_embeds(context, unprocessed=meta.get(\"unprocessed_ltxav_embeds\", False))\n            video_tokens = processed[..., :dm.cross_attention_dim].float()\n            audio_tokens = processed[..., dm.cross_attention_dim:].float()\n            seconds = float(head(video_tokens, audio_tokens)[0])\n\n        num_frames = comfy.ldm.lightricks.duration_head.seconds_to_num_frames(","sourceCodeStart":1135,"sourceCodeEnd":1171,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_extras/nodes_lt.py#L1135-L1171","documentation":"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.","triggerScenarios":"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.","commonSituations":"Building the LTX-2 duration workflow and grabbing the wrong loader node from the menu; reusing a template where the patch slot was rewired.","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."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"import comfy.ldm.lightricks.duration_head as dh\nassert isinstance(duration_head.model, dh.DurationHead), (\n    \"duration_head input must come from the LTX duration-head loader, not a generic model patch\")","typeGuard":"def is_ltx_duration_head(model_patch) -> bool:\n    import comfy.ldm.lightricks.duration_head as dh\n    return isinstance(getattr(model_patch, \"model\", None), dh.DurationHead)","tryCatchPattern":null,"preventionTips":["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."],"tags":["ltx","model-patch","duration-head","type-guard","workflow"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}