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
- Use channel_axis=2 (channels-last, the common case) or channel_axis=0 (channels-first)
- 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
- Standardize data to channels-last before augmentation
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
- 'row_axis', 'col_axis', and 'channel_axis' must be distinct
- Invalid axis' indices: {actual_indices - valid_indices}
- Input arrays must be multi-channel 2D images.
- `adapt()` can only be called on a tf.data.Dataset or a dict
- Invalid value for argument `output_mode`. Expected one of {a
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/669fd345ea3a5b50.
Report an issue: GitHub.