keras-team/keras · error · ValueError

Channels are allowed and the first and last dimensions.

Error message

Channels are allowed and the first and last dimensions.

What it means

The legacy affine transform code can only move the channel axis to the first or last position of the 3D tensor because it transposes with hardcoded layouts. If channel_axis is 1 (channels in the middle) it raises this ValueError. The message itself contains a Keras typo ('and' should read 'in').

Source

Thrown at keras/src/legacy/preprocessing/image.py:1810

    # 1. x must 2D image with one or more channels (i.e., a 3D tensor)
    # 2. channels must be either first or last dimension
    if np.unique([row_axis, col_axis, channel_axis]).size != 3:
        raise ValueError(
            "'row_axis', 'col_axis', and 'channel_axis' must be distinct"
        )

    # shall we support negative indices?
    valid_indices = set([0, 1, 2])
    actual_indices = set([row_axis, col_axis, channel_axis])
    if actual_indices != valid_indices:
        raise ValueError(
            f"Invalid axis' indices: {actual_indices - valid_indices}"
        )

    if x.ndim != 3:
        raise ValueError("Input arrays must be multi-channel 2D images.")
    if channel_axis not in [0, 2]:
        raise ValueError(
            "Channels are allowed and the first and last dimensions."
        )

    transform_matrix = None
    if theta != 0:
        theta = np.deg2rad(theta)
        rotation_matrix = np.array(
            [
                [np.cos(theta), -np.sin(theta), 0],
                [np.sin(theta), np.cos(theta), 0],
                [0, 0, 1],
            ]
        )
        transform_matrix = rotation_matrix

    if tx != 0 or ty != 0:
        shift_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
        if transform_matrix is None:

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Use channel_axis=2 (channels-last, the common case) or channel_axis=0 (channels-first)
  2. If channels really sit in the middle, transpose first: img = np.moveaxis(img, 1, -1) and pass channel_axis=2

Example fix

# before
apply_affine_transform(img, theta=10, row_axis=0, col_axis=2, channel_axis=1)
# after
img_moved = np.moveaxis(img, 1, -1)
apply_affine_transform(img_moved, theta=10, row_axis=0, col_axis=1, channel_axis=2)
Defensive patterns

Strategy: validation

Validate before calling

if channel_axis not in (0, 2):
    img = np.moveaxis(img, channel_axis, -1)
    channel_axis = 2

Type guard

def supported_channel_axis(ch):
    return ch in (0, 2)

Prevention

When it happens

Trigger: Calling apply_affine_transform with channel_axis=1, e.g. row_axis=0, col_axis=2, channel_axis=1, an arrangement the implementation cannot handle.

Common situations: Programmatically permuting axes for exotic memory layouts, or adapting someone else's augmentation snippet and swapping the axis order incorrectly.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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