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. Received: x={x}

What it means

keras.ops.fft (1D FFT) requires its input to be a tuple/list of exactly two tensors: the real and imaginary parts of a complex signal. During symbolic shape inference (compute_output_spec), the op rejects anything that is not a 2-element sequence, such as a single tensor or a numpy array.

Source

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

    Example:

    >>> x = keras.ops.convert_to_tensor([1, 2, 3, 4, 5, 6])
    >>> extract_sequences(x, 3, 2)
    array([[1, 2, 3],
       [3, 4, 5]])
    """
    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. "

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Pass a tuple (real, imag): keras.ops.fft((real, imag))
  2. If you have one complex-valued tensor, split it into its real and imag halves before calling
  3. Use keras.ops.stft or keras.ops.rfft for real-only signals instead of fft
  4. Check len(x)==2 and that both elements are tensors before the call in data pipelines

Example fix

# before
spec = keras.ops.fft(signal)
# after
spec = keras.ops.fft((signal_real, signal_imag))
Defensive patterns

Strategy: type-guard

Validate before calling

assert isinstance(x, (tuple, list)) and len(x) == 2, 'fft expects (real, imag)'

Type guard

def is_complex_pair(x):
    return isinstance(x, (tuple, list)) and len(x) == 2

Prevention

When it happens

Trigger: Calling keras.ops.fft(x) with a single real tensor, a stack of real+imag along an axis, a list of 3+ tensors, or a plain numpy array instead of a tuple of two KerasTensors.

Common situations: Migrating code from np.fft.fft or torch.fft (which take one complex tensor) to Keras 3, or assuming Keras auto-converts complex inputs; also passing the output of zip or an unpacked *args incorrectly.

Related errors


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