Comfy-Org/ComfyUI · error · ValueError

PidNet requires lq_latent — attach via PiDConditioning

Error message

PidNet requires lq_latent — attach via PiDConditioning

What it means

PidNet (pixel-level degradation network for PixDiT super-resolution) requires a low-quality latent ('lq_latent') every forward pass; it is the essential input that the Pi gates inject into the patch/pixel blocks. The ValueError fires when the model is run without lq_latent, i.e. the PiD conditioning was never attached to the model input. The message points you to the intended API: supply it via the PiDConditioning node.

Source

Thrown at comfy/ldm/pixeldit/pid.py:236

            device=device, dtype=dtype, **rope_opts,
        )

    def _pre_patch_block(self, s, i, pid_lq_features, pid_degrade_sigma, **kwargs):
        if not self.lq_proj.is_gate_active(i):
            return s
        out_idx = self.lq_proj.output_index(i)
        if out_idx >= len(pid_lq_features):
            return s
        return self.lq_proj.gate(s, pid_lq_features[out_idx], pid_degrade_sigma, out_idx)

    def _pre_pixel_blocks(self, s, pid_pit_lq_feature=None, pid_degrade_sigma=None, **kwargs):
        if pid_pit_lq_feature is None:
            return s
        return self.pit_lq_gate(s, pid_pit_lq_feature, pid_degrade_sigma)

    def _forward(self, x, timesteps, context=None, attention_mask=None, transformer_options={}, lq_latent=None, degrade_sigma=None, **kwargs):
        if lq_latent is None:
            raise ValueError("PidNet requires lq_latent — attach via PiDConditioning")
        expected_c = self.lq_proj.latent_channels
        if lq_latent.shape[1] != expected_c:
            raise ValueError(
                f"Input latent has {lq_latent.shape[1]} channels, this model variant expects {expected_c}. "
                f"Flux1/SD3 = 16 channels, Flux2 = 128 channels."
            )
        B = x.shape[0]
        # Match the backbone's pad_to_patch_size (round up) so the LQ grid lines up with the patch stream.
        Hs = -(-x.shape[2] // self.patch_size)
        Ws = -(-x.shape[3] // self.patch_size)

        degrade_sigma = degrade_sigma.to(device=x.device, dtype=torch.float32).reshape(-1)
        if degrade_sigma.numel() == 1 and B > 1:
            degrade_sigma = degrade_sigma.expand(B).contiguous()

        lq_features = self.lq_proj(lq_latent=lq_latent.to(x), target_pH=Hs, target_pW=Ws)
        pit_lq_feature = lq_features.pop() if self.pit_lq_inject else None

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Add the PiDConditioning node to the workflow and connect your low-quality image/latent so lq_latent reaches the model.
  2. Verify the conditioning chain is not bypassed/muted (bypassed nodes pass None through).
  3. Check that the LQ image and the target generation share resolution settings — the LQ latent grid must line up with the patch stream.
  4. If you do not want super-resolution behavior, load the plain PixDiT_T2I model instead of the PiD variant.
Defensive patterns

Strategy: validation

Validate before calling

def check_pid_inputs(lq_latent):
    if lq_latent is None:
        raise ValueError("PiD workflows require an LQ latent via PiDConditioning; connect the LQ image input")
    return lq_latent

Prevention

When it happens

Trigger: Loading a PixDiT PiD-LoRA/model and running a normal text-to-image sampler pass with no PiDConditioning input attached; calling model forward directly without the lq_latent kwarg; a workflow that connects the PiD model but forgets the LQ image/latent conditioning input.

Common situations: User loads a PiD (photo-realistic image degradation/super-resolution) checkpoint but wires it like a plain T2I model; the LQ image input node is muted or bypassed in the workflow; a converted workflow from another UI dropped the PiD conditioning link.

Related errors


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