{"record":{"id":"2648568af06fdef1","repo":"Comfy-Org/ComfyUI","slug":"joyimagetemodel-encoded-sequence-length-out-shap","errorCode":null,"errorMessage":"JoyImageTEModel: encoded sequence length {out.shape[1]} is shorter than drop_idx={JOYIMAGE_DROP_IDX}; the prompt did not include the template prefix.","messagePattern":"JoyImageTEModel: encoded sequence length (.+?) is shorter than drop_idx=(.+?); the prompt did not include the template prefix\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy/text_encoders/joyimage.py","lineNumber":77,"sourceCode":"            device=device, layer=layer, layer_idx=layer_idx, textmodel_json_config={},\n            # JoyImage conditions on the pre-final-norm output of the last decoder layer.\n            dtype=dtype, special_tokens={\"pad\": PAD_TOKEN}, layer_norm_hidden_state=False,\n            model_class=Qwen3VL8B_JoyImage, enable_attention_masks=attention_mask,\n            return_attention_masks=attention_mask, model_options=model_options,\n        )\n\n\nclass JoyImageTEModel(sd1_clip.SD1ClipModel):\n    def __init__(self, device=\"cpu\", dtype=None, model_options={}):\n        super().__init__(\n            device=device, dtype=dtype, name=\"qwen3vl_8b\",\n            clip_model=_JoyImageClipModel, model_options=model_options,\n        )\n\n    def encode_token_weights(self, token_weight_pairs):\n        out, pooled, extra = super().encode_token_weights(token_weight_pairs)\n        if out.shape[1] <= JOYIMAGE_DROP_IDX:\n            raise ValueError(\n                f\"JoyImageTEModel: encoded sequence length {out.shape[1]} is shorter \"\n                f\"than drop_idx={JOYIMAGE_DROP_IDX}; the prompt did not include the \"\n                f\"template prefix.\"\n            )\n        out = out[:, JOYIMAGE_DROP_IDX:]\n        if \"attention_mask\" in extra:\n            extra[\"attention_mask\"] = extra[\"attention_mask\"][:, JOYIMAGE_DROP_IDX:]\n        return out, pooled, extra\n\n\ndef te(dtype_llama=None, llama_quantization_metadata=None):\n    class JoyImageTEModel_(JoyImageTEModel):\n        def __init__(self, device=\"cpu\", dtype=None, model_options={}):\n            if llama_quantization_metadata is not None:\n                model_options = model_options.copy()\n                model_options[\"quantization_metadata\"] = llama_quantization_metadata\n            if dtype_llama is not None:\n                dtype = dtype_llama","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy/text_encoders/joyimage.py#L59-L95","documentation":"JoyImage's Qwen3-VL-based text encoder expects the prompt to start with a fixed template prefix of 34 tokens (JOYIMAGE_DROP_IDX = 34), which encode_token_weights strips after encoding. If the encoded sequence is <= 34 tokens, the prefix was never added (or the tokenizer/te was swapped), so slicing would destroy the whole sequence and the code raises instead of producing garbage conditioning.","triggerScenarios":"Calling JoyImageTEModel.encode_token_weights on token weights whose encoded length is <= 34 tokens — typically because the JoyCaption template prompt ('<|begin_of_text|>...description...') was not prepended by the loader/wrapper before calling the model.","commonSituations":"User wired a generic CLIPTextEncode-style node directly to the JoyImage encoder, bypassing the template-building wrapper; user overrode tokenize_with_weights without the template; mismatched tokenizer produced far fewer tokens than expected.","solutions":["Use the JoyImage-provided node/wrapper that builds the caption template prompt so the 34-token prefix is present before encoding","If calling encode_token_weights directly, prepend the expected JoyCaption template prefix to the prompt text","Verify the tokenizer bundled with the encoder matches (qwen3vl_8b); a wrong tokenizer yields short sequences and the same failure"],"exampleFix":"// before\nout, pooled, extra = te_model.encode_token_weights([[(t, 1.0) for t in plain_tokens]])\n\n# after\nprompt = joyimage_build_template(plain_text)  # adds the 34-token template prefix\nout, pooled, extra = te_model.encode_token_weights([[(t, 1.0) for t in tokenize(prompt)]])","handlingStrategy":"validation","validationCode":"from comfy.text_encoders.joyimage import JOYIMAGE_DROP_IDX\nn = out.shape[1]\nassert n > JOYIMAGE_DROP_IDX, f'prompt missing template prefix ({n} <= {JOYIMAGE_DROP_IDX} tokens)'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always route JoyImage prompts through the template-building wrapper/node","Never call encode_token_weights with bare user text for this encoder"],"tags":["text-encoder","joyimage","prompt-template","conditioning"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}