Comfy-Org/ComfyUI · error · RuntimeError

ERROR: clip input is invalid: None\n\nIf the clip is from a

Error message

ERROR: clip input is invalid: None\n\nIf the clip is from a checkpoint loader node your checkpoint does not contain a valid clip or text encoder model.

What it means

Raised by the Lumina2 text-encode node when the clip input is None. In ComfyUI, a CheckpointLoader that finds no CLIP/text-encoder weights in the checkpoint yields clip=None, and optional typing lets None reach the node. The long message explicitly points at checkpoint loaders whose file lacks a valid text encoder.

Source

Thrown at comfy_extras/nodes_lumina2.py:111

                io.String.Input(
                    "user_prompt",
                    multiline=True,
                    dynamic_prompts=True,
                    tooltip="The text to be encoded.",
                ),
                io.Clip.Input("clip", tooltip="The CLIP model used for encoding the text."),
            ],
            outputs=[
                io.Conditioning.Output(
                    tooltip="A conditioning containing the embedded text used to guide the diffusion model.",
                ),
            ],
        )

    @classmethod
    def execute(cls, clip, user_prompt, system_prompt) -> io.NodeOutput:
        if clip is None:
            raise RuntimeError("ERROR: clip input is invalid: None\n\nIf the clip is from a checkpoint loader node your checkpoint does not contain a valid clip or text encoder model.")
        system_prompt = cls.SYSTEM_PROMPT[system_prompt]
        prompt = f'{system_prompt} <Prompt Start> {user_prompt}'
        tokens = clip.tokenize(prompt)
        return io.NodeOutput(clip.encode_from_tokens_scheduled(tokens))


class Lumina2Extension(ComfyExtension):
    @override
    async def get_node_list(self) -> list[type[io.ComfyNode]]:
        return [
            CLIPTextEncodeLumina2,
            RenormCFG,
        ]


async def comfy_entrypoint() -> Lumina2Extension:
    return Lumina2Extension()

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Load the text encoder separately with a CLIPLoader (DualCLIPLoader/Gemma-style loader appropriate for Lumina2) and connect it to the clip input.
  2. If the checkpoint is supposed to contain a CLIP, verify the file integrity and that it was exported with text encoder weights included.
  3. Do not wire the CLIP output of a diffusion-only checkpoint loader into this node.

Example fix

# before
ckpt = CheckpointLoaderSimple('lumina2_diffusion_only.safetensors')
cond = CLIPTextEncodeLumina2(ckpt.CLIP, ...)   # clip is None -> raises

# after
clip = CLIPLoader('umt5_xxl.safetensors', type='lumina2')
cond = CLIPTextEncodeLumina2(clip, ...)
Defensive patterns

Strategy: type-guard

Validate before calling

if clip is None:
    raise RuntimeError(
        "clip is None: this checkpoint has no text encoder. "
        "Load the text encoder with a CLIPLoader and connect that instead.")

Type guard

def has_valid_clip(clip) -> bool:
    return clip is not None and hasattr(clip, "tokenize") and hasattr(clip, "encode_from_tokens_scheduled")

Try / catch

try:
    cond = CLIPTextEncodeLumina2.execute(clip, prompt, system)
except RuntimeError as e:
    if "clip input is invalid" in str(e):
        clip = load_separate_text_encoder("lumina2")
        cond = CLIPTextEncodeLumina2.execute(clip, prompt, system)
    else:
        raise

Prevention

When it happens

Trigger: Loading a checkpoint that is diffusion-model-only (e.g. a raw Lumina2 or flow-matching DiT .safetensors without an embedded text encoder) through CheckpointLoader and wiring its CLIP output here; a corrupted or mis-packaged checkpoint where the text_encoder keys are absent.

Common situations: Using diffusers-format or single-tensor model files renamed to look like checkpoints; new Lumina2 releases that ship the text encoder separately.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/a09979df353b6db9. Report an issue: GitHub.