keras-team/keras · error · ValueError

Input `x` should be a tuple of two tensors - real and imagin

Error message

Input `x` should be a tuple of two tensors - real and imaginary. Both the real and imaginary parts should have the same shape. Received: x[0].shape = {real.shape}, x[1].shape = {imag.shape}

What it means

The real and imaginary tensors passed to keras.ops.fft must have identical shapes; the op computes element-wise 1D FFT over the last axis for both parts. Symbolic shape inference raises when x[0].shape != x[1].shape.

Source

Thrown at keras/src/ops/math.py:509

    if any_symbolic_tensors((x,)):
        return ExtractSequences(sequence_length, sequence_stride).symbolic_call(
            x
        )
    return backend.math.extract_sequences(x, sequence_length, sequence_stride)


class FFT(Operation):
    def compute_output_spec(self, x):
        if not isinstance(x, (tuple, list)) or len(x) != 2:
            raise ValueError(
                "Input `x` should be a tuple of two tensors - real and "
                f"imaginary. Received: x={x}"
            )

        real, imag = x
        # Both real and imaginary parts should have the same shape.
        if real.shape != imag.shape:
            raise ValueError(
                "Input `x` should be a tuple of two tensors - real and "
                "imaginary. Both the real and imaginary parts should have the "
                f"same shape. Received: x[0].shape = {real.shape}, "
                f"x[1].shape = {imag.shape}"
            )

        # We are calculating 1D FFT. Hence, rank >= 1.
        if len(real.shape) < 1:
            raise ValueError(
                f"Input should have rank >= 1. "
                f"Received: input.shape = {real.shape}"
            )

        # The axis along which we are calculating FFT should be fully-defined.
        m = real.shape[-1]
        if m is None:
            raise ValueError(
                f"Input should have its last dimension fully-defined. "

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Print/inspect x[0].shape and x[1].shape right before the call and reconcile padding/windowing so they match
  2. Recompute both parts from the same source tensor (e.g. real=x.real, imag=x.imag of one complex array)
  3. In functional models, ensure both inputs flow from the same upstream layer so symbolic shapes stay identical
  4. Fix slicing: use the same index range for both parts

Example fix

# before
out = keras.ops.fft((real[:, :8], imag[:, :16]))
# after
out = keras.ops.fft((real[:, :8], imag[:, :8]))
Defensive patterns

Strategy: validation

Validate before calling

assert real.shape == imag.shape, f'{real.shape} != {imag.shape}'

Try / catch

try:
    out = keras.ops.fft((real, imag))
except ValueError as e:
    if 'same shape' in str(e):
        imag = pad_to(imag, real.shape)
        out = keras.ops.fft((real, imag))
    else:
        raise

Prevention

When it happens

Trigger: Passing real of shape (2, 8) and imag of shape (2, 16); slicing real and imag from differently padded sequences; one part having an extra leading batch dimension.

Common situations: Building real/imag parts in separate preprocessing steps (e.g. imag computed from a different window length), or broadcasting bugs where one branch adds a dimension. Partially-defined (None) dims also compare unequal during functional-model building.

Related errors


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/5fe9e751631cc2ea. Report an issue: GitHub.