invoke-ai/InvokeAI · error · ValueError

LoRA "{lora_key}" already applied to CLIP encoder.

Error message

LoRA "{lora_key}" already applied to CLIP encoder.

What it means

Same duplicate-guard as the transformer check, but for the CLIP text encoder component. The loader detects that the given LoRA key is already attached to self.clip.loras and raises ValueError before applying again. Double-applying a LoRA to CLIP would double the text-embedding delta.

Source

Thrown at invokeai/app/invocations/flux_lora_loader.py:74

    )
    t5_encoder: T5EncoderField | None = InputField(
        default=None,
        title="T5 Encoder",
        description=FieldDescriptions.t5_encoder,
        input=Input.Connection,
    )

    def invoke(self, context: InvocationContext) -> FluxLoRALoaderOutput:
        lora_key = self.lora.key

        if not context.models.exists(lora_key):
            raise ValueError(f"Unknown lora: {lora_key}!")

        # Check for existing LoRAs with the same key.
        if self.transformer and any(lora.lora.key == lora_key for lora in self.transformer.loras):
            raise ValueError(f'LoRA "{lora_key}" already applied to transformer.')
        if self.clip and any(lora.lora.key == lora_key for lora in self.clip.loras):
            raise ValueError(f'LoRA "{lora_key}" already applied to CLIP encoder.')
        if self.t5_encoder and any(lora.lora.key == lora_key for lora in self.t5_encoder.loras):
            raise ValueError(f'LoRA "{lora_key}" already applied to T5 encoder.')

        output = FluxLoRALoaderOutput()

        # Attach LoRA layers to the models.
        if self.transformer is not None:
            output.transformer = self.transformer.model_copy(deep=True)
            output.transformer.loras.append(
                LoRAField(
                    lora=self.lora,
                    weight=self.weight,
                )
            )
        if self.clip is not None:
            output.clip = self.clip.model_copy(deep=True)
            output.clip.loras.append(
                LoRAField(

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Remove the duplicate loader/edge targeting the CLIP encoder
  2. Use a distinct LoRA model key if you actually intend a different LoRA on CLIP
  3. Rebuild the graph so CLIP-side LoRA application happens exactly once
  4. Check node connections in the InvokeAI canvas for accidental double-links

Example fix

// before
clip_loader = FluxLoRALoader(lora=lora_key, weight=0.7)  # same lora_key used again downstream
// after
single_loader = FluxLoRALoader(lora=lora_key, weight=0.7)  # reuse its output instead of loading again
Defensive patterns

Strategy: validation

Validate before calling

clip_keys = [l.lora.key for l in clip.loras] if clip else []
assert lora_key not in clip_keys, f"LoRA {lora_key} already on CLIP"

Type guard

def clip_lora_free(clip, lora_key: str) -> bool:
    return not clip or not any(l.lora.key == lora_key for l in clip.loras)

Try / catch

try:
    output = loader.invoke(context)
except ValueError as e:
    if 'already applied to CLIP' in str(e):
        output = None  # skip, already loaded on CLIP
    else:
        raise

Prevention

When it happens

Trigger: invoke() runs with self.clip set and any lora in self.clip.loras already has key == lora_key — same LoRA fed to the CLIP encoder path twice in one graph execution.

Common situations: Wired the same LoRA loader output into both a FLUX LoRA field and a CLIP LoRA field expecting separate applications; graphs built programmatically that append the CLIP-targeted loader twice.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/be9eb04cbc9714c0. Report an issue: GitHub.