keras-team/keras · error · ValueError

Method `compute_output_shape()` of layer {self.__class__.__n

Error message

Method `compute_output_shape()` of layer {self.__class__.__name__} is returning a type that cannot be interpreted as a shape. It should return a shape tuple. Received: {output_shape}

What it means

compute_output_spec() falls back to the layer's compute_output_shape(); whatever that returns must be convertible to a shape tuple/list/dict. If the returned object cannot be coerced with tuple(), Keras raises this error showing the offending value.

Source

Thrown at keras/src/layers/layer.py:1249

            shapes_dict = update_shapes_dict_for_target_fn(
                self.compute_output_shape,
                shapes_dict=shapes_dict,
                call_spec=call_spec,
                class_name=self.__class__.__name__,
            )
            output_shape = self.compute_output_shape(**shapes_dict)

            if (
                isinstance(output_shape, list)
                and output_shape
                and isinstance(output_shape[0], (int, type(None)))
            ):
                output_shape = tuple(output_shape)
            if not isinstance(output_shape, (list, tuple, dict)):
                try:
                    output_shape = tuple(output_shape)
                except:
                    raise ValueError(
                        "Method `compute_output_shape()` of layer "
                        f"{self.__class__.__name__} is returning "
                        "a type that cannot be interpreted as a shape. "
                        "It should return a shape tuple. "
                        f"Received: {output_shape}"
                    )
            if (
                isinstance(output_shape, tuple)
                and output_shape
                and isinstance(output_shape[0], (int, type(None)))
            ):
                return KerasTensor(output_shape, dtype=self.compute_dtype)
            # Case: nested. Could be a tuple/list of shapes, or a dict of
            # shapes. Could be deeply nested.
            return tree.map_shape_structure(
                lambda s: KerasTensor(s, dtype=self.compute_dtype), output_shape
            )

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Make compute_output_shape() return a plain tuple of ints (or list/dict for multi-output)
  2. If returning dynamic shapes, ensure the object is tuple()-convertible (e.g. tuple(tensor_shape)
  3. Test compute_output_spec directly with keras.ops.is_keras_tensor inputs

Example fix

# before
def compute_output_shape(self, input_shape):
    return input_shape  # may be a single int
# after
def compute_output_shape(self, input_shape):
    return tuple(input_shape)[:-1] + (self.units,)
Defensive patterns

Strategy: validation

Validate before calling

out = layer.compute_output_shape(input_shape)
assert isinstance(out, (list, tuple, dict)) or tuple(out), out

Type guard

def is_valid_shape(s):
    try:
        tuple(s)
        return True
    except Exception:
        return False

Prevention

When it happens

Trigger: A custom layer's compute_output_shape() returns a TensorShape in an odd backend, a tensor, a string, or None; returning a scalar/int instead of a tuple; returning a shape object from another library.

Common situations: Writing custom layers with dynamic output shapes; mixing TF TensorShape with Keras 3 multi-backend code; returning shape logic that degenerates to a non-iterable.

Related errors


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