Comfy-Org/ComfyUI · error · ValueError

Output dims {output.shape} don't match x dims {x.shape} - th

Error message

Output dims {output.shape} don't match x dims {x.shape} - this is no good

What it means

EasyCache update_cache_diff raises this when the block output tensor's trailing dims differ from the input x dims while writing the cache diff. As with apply_cache_diff, mismatched dims can be sliced (cosmos world2video), but only with allow_mismatch=True; otherwise the node treats the inconsistency as fatal rather than caching a misaligned residual.

Source

Thrown at comfy_extras/nodes_easycache.py:302

                        skip_this_dim = False
                        continue
                    if dim_u != dim_x:
                        if self.cut_from_start:
                            slicing.append(slice(dim_x-dim_u, None))
                        else:
                            slicing.append(slice(None, dim_u))
                    else:
                        slicing.append(slice(None))
                batch_slice = batch_slice + slicing
            x[tuple(batch_slice)] += cache_diffs[uuid].to(x.device)
        return x

    def update_cache_diff(self, output: torch.Tensor, x: torch.Tensor, uuids: list[UUID], is_audio: bool = False):
        cache_diffs = self.uuid_cache_diffs_audio if is_audio else self.uuid_cache_diffs
        # if output dims don't match x dims, cut off excess and hope for the best (cosmos world2video)
        if output.shape[1:] != x.shape[1:]:
            if not self.allow_mismatch:
                raise ValueError(f"Output dims {output.shape} don't match x dims {x.shape} - this is no good")
            slicing = []
            skip_dim = True
            for dim_o, dim_x in zip(output.shape, x.shape):
                if not skip_dim and dim_o != dim_x:
                    if self.cut_from_start:
                        slicing.append(slice(dim_x-dim_o, None))
                    else:
                        slicing.append(slice(None, dim_o))
                else:
                    slicing.append(slice(None))
                skip_dim = False
            x = x[tuple(slicing)]
        diff = output - x
        batch_offset = diff.shape[0] // len(uuids)
        for i, uuid in enumerate(uuids):
            cache_diffs[uuid] = diff[i*batch_offset:(i+1)*batch_offset, ...]

    def has_first_cond_uuid(self, uuids: list[UUID]) -> bool:

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Set allow_mismatch=True on the cache node so x is sliced to the output shape before the diff is stored (use cut_from_start to control which side is kept).
  2. If the model should have matching dims, verify resolution/frame settings are unchanged across steps.
  3. Recompute caches from scratch after any shape-affecting change.

Example fix

// before
node.allow_mismatch = False
// after
node.allow_mismatch = True
node.cut_from_start = True  # keep the tail of x that matches the output
Defensive patterns

Strategy: validation

Validate before calling

if output.shape[1:] != x.shape[1:] and not cache.allow_mismatch:
    raise ValueError(
        f'block output {output.shape} differs from input {x.shape}; '
        'enable allow_mismatch to slice, or stop caching this block')

Prevention

When it happens

Trigger: A model block whose output sequence length differs from its input (variable-length/video transformers); caching enabled on such a block with allow_mismatch at its default false.

Common situations: Enabling EasyCache on Cosmos world2video or other models with input/output length changes; resolution or frame-count changes between steps; first adoption of the cache node without configuring allow_mismatch.

Related errors


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