Comfy-Org/ComfyUI · error · ValueError

Either spatial_upsample or temporal_upsample must be True

Error message

Either spatial_upsample or temporal_upsample must be True

What it means

Each upsampler stage must increase either spatial resolution (2D pixel-shuffle after a Conv2d) or temporal length (Conv3d + 1D pixel-shuffle). If both flags are False the block would be an identity chain with a final conv, which is not a supported configuration, so the constructor rejects it.

Source

Thrown at comfy/ldm/lightricks/latent_upsampler.py:214

                PixelShuffleND(3),
            )
        elif spatial_upsample:
            if rational_resampler:
                self.upsampler = SpatialRationalResampler(
                    mid_channels=mid_channels, scale=self.spatial_scale, operations=operations
                )
            else:
                self.upsampler = nn.Sequential(
                    operations.Conv2d(mid_channels, 4 * mid_channels, kernel_size=3, padding=1),
                    PixelShuffleND(2),
                )
        elif temporal_upsample:
            self.upsampler = nn.Sequential(
                operations.Conv3d(mid_channels, 2 * mid_channels, kernel_size=3, padding=1),
                PixelShuffleND(1),
            )
        else:
            raise ValueError(
                "Either spatial_upsample or temporal_upsample must be True"
            )

        self.post_upsample_res_blocks = nn.ModuleList(
            [ResBlock(mid_channels, dims=dims, operations=operations) for _ in range(num_blocks_per_stage)]
        )

        self.final_conv = Conv(mid_channels, in_channels, kernel_size=3, padding=1)

    def get_dtype(self):
        return getattr(self.initial_conv, "weight_comfy_model_dtype", self.initial_conv.weight.dtype)

    def forward(self, latent: torch.Tensor) -> torch.Tensor:
        b, c, f, h, w = latent.shape

        if self.dims == 2:
            x = rearrange(latent, "b c f h w -> (b f) c h w")
            x = self.initial_conv(x)

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Enable at least one of spatial_upsample or temporal_upsample per stage
  2. If you truly need a non-upsampling residual stage, use the plain ResBlock stack classes instead of this upsampler
  3. Audit the config loader for boolean coercion bugs (e.g. 'false' strings, missing keys defaulting wrong)

Example fix

# before
stage = UpsampleStage(..., spatial_upsample=False, temporal_upsample=False)
# after
stage = UpsampleStage(..., spatial_upsample=True, temporal_upsample=False)
Defensive patterns

Strategy: validation

Validate before calling

assert spatial_upsample or temporal_upsample, "pick at least one upsample mode"

Prevention

When it happens

Trigger: Building the upsampler with spatial_upsample=False, temporal_upsample=False; typically a config where one flag was expected to default True but was explicitly disabled, or a yaml with a typo making both false.

Common situations: Config generation code that sets flags from a mode string and falls through to False/False, or disabling temporal upsampling on a stage that also had spatial off.

Related errors


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