{"record":{"id":"618295eeab498a6c","repo":"keras-team/keras","slug":"invalid-transform-rank-expected-rank-1-single-tr-618295","errorCode":null,"errorMessage":"Invalid transform rank: expected rank 1 (single transform) or rank 2 (batch of transforms). Received input with shape: transform.shape={transform.shape}","messagePattern":"Invalid transform rank: expected rank 1 \\(single transform\\) or rank 2 \\(batch of transforms\\)\\. Received input with shape: transform\\.shape=(.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/ops/image.py","lineNumber":469,"sourceCode":"    def call(self, images, transform):\n        return backend.image.affine_transform(\n            images,\n            transform,\n            interpolation=self.interpolation,\n            fill_mode=self.fill_mode,\n            fill_value=self.fill_value,\n            data_format=self.data_format,\n        )\n\n    def compute_output_spec(self, images, transform):\n        if len(images.shape) not in (3, 4):\n            raise ValueError(\n                \"Invalid images rank: expected rank 3 (single image) \"\n                \"or rank 4 (batch of images). Received input with shape: \"\n                f\"images.shape={images.shape}\"\n            )\n        if len(transform.shape) not in (1, 2):\n            raise ValueError(\n                \"Invalid transform rank: expected rank 1 (single transform) \"\n                \"or rank 2 (batch of transforms). Received input with shape: \"\n                f\"transform.shape={transform.shape}\"\n            )\n        return KerasTensor(images.shape, dtype=images.dtype)\n\n\n@keras_export(\"keras.ops.image.affine_transform\")\ndef affine_transform(\n    images,\n    transform,\n    interpolation=\"bilinear\",\n    fill_mode=\"constant\",\n    fill_value=0,\n    data_format=None,\n):\n    \"\"\"Applies the given transform(s) to the image(s).\n","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/ops/image.py#L451-L487","documentation":"The same affine-transform op validates the transform argument: it must be rank 1 (a single transform vector, typically length 8) or rank 2 (a batch of transform vectors, one per image). Rank-0 scalars, rank-3 arrays, or per-pixel transform stacks raise this ValueError.","triggerScenarios":"Passing a scalar or a (N,1,8) stack to affine_transform; passing transformation matrices shaped (3,3) for a projective op expecting flat vectors; batch size mismatch is not checked here but rank is.","commonSituations":"Converting OpenCV 2x3/3x3 matrices to Keras transform vectors and keeping an extra axis; building transforms with np.array([t1, t2]) where each ti is itself a sequence, accidentally making rank 3.","solutions":["Flatten each transform to a 1-D vector and stack: transforms = np.stack([t.flatten() for t in ts]) giving rank 2","For a single image, pass one flat vector (rank 1)","Check len(transform.shape) in (1, 2) before calling"],"exampleFix":"# before\ny = keras.ops.image.affine_transform(imgs, transforms)  # transforms.shape=(N,1,8)\n\n# after\ntransforms = transforms.reshape((-1, 8))  # rank 2\ny = keras.ops.image.affine_transform(imgs, transforms)","handlingStrategy":"type-guard","validationCode":"t = np.asarray(transform)\nassert t.ndim in (1, 2), f'transform rank {t.ndim}, expected 1 or 2'\nif t.ndim == 2:\n    assert t.shape[0] in (1, images.shape[0])","typeGuard":"def is_valid_transform(t) -> bool:\n    return np.asarray(t).ndim in (1, 2)","tryCatchPattern":null,"preventionTips":["Flatten each transform matrix to a 1-D vector before stacking","Match the transforms batch dim to the images batch dim"],"tags":["keras","image","affine-transform","rank-validation"],"backgroundTag":"invalid-argument-shape","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}