{"record":{"id":"1381e9d120194344","repo":"keras-team/keras","slug":"values-in-cropping-argument-should-be-smaller-th-1381e9","errorCode":null,"errorMessage":"Values in `cropping` argument should be smaller than the corresponding spatial dimension of the input. Received: input_shape={input_shape}, cropping={self.cropping}","messagePattern":"Values in `cropping` argument should be smaller than the corresponding spatial dimension of the input\\. Received: input_shape=(.+?), cropping=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/reshaping/cropping3d.py","lineNumber":114,"sourceCode":"                \"((left_dim1_crop, right_dim1_crop),\"\n                \" (left_dim2_crop, right_dim2_crop),\"\n                \" (left_dim3_crop, right_dim2_crop)). \"\n                f\"Received: {cropping}.\"\n            )\n        self.input_spec = InputSpec(ndim=5)\n\n    def compute_output_shape(self, input_shape):\n        if self.data_format == \"channels_first\":\n            spatial_dims = list(input_shape[2:5])\n        else:\n            spatial_dims = list(input_shape[1:4])\n\n        for index in range(0, 3):\n            if spatial_dims[index] is None:\n                continue\n            spatial_dims[index] -= sum(self.cropping[index])\n            if spatial_dims[index] <= 0:\n                raise ValueError(\n                    \"Values in `cropping` argument should be smaller than the \"\n                    \"corresponding spatial dimension of the input. Received: \"\n                    f\"input_shape={input_shape}, cropping={self.cropping}\"\n                )\n\n        if self.data_format == \"channels_first\":\n            return (input_shape[0], input_shape[1], *spatial_dims)\n        else:\n            return (input_shape[0], *spatial_dims, input_shape[4])\n\n    def call(self, inputs):\n        if self.data_format == \"channels_first\":\n            spatial_dims = list(inputs.shape[2:5])\n        else:\n            spatial_dims = list(inputs.shape[1:4])\n\n        for index in range(0, 3):\n            if spatial_dims[index] is None:","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/reshaping/cropping3d.py#L96-L132","documentation":"Raised by Cropping3D.compute_output_shape when the sum of the crop amounts for any spatial axis is greater than or equal to that axis's size in the input shape, which would leave a non-positive output dimension. Keras validates this eagerly so an invalid crop fails at shape-inference time instead of producing a corrupt tensor. The check is skipped for unknown (None) dimensions.","triggerScenarios":"Calling Cropping3D(cropping=((a,b),(c,d),(e,f))) on an input whose spatial dims (depth, height, width for channels_last) satisfy dim - sum(crop_pair) <= 0 for any axis, e.g. Cropping3D(cropping=((2,2),(2,2),(2,2))) on a (1, 3, 3, 3, 4) tensor. Triggered when building the model or during compute_output_shape, even before real data flows.","commonSituations":"Copy-pasting a Cropping2D/Cropping3D config from a model built for larger inputs (e.g. 224x224 images) onto small inputs; forgetting that cropping pairs are (before, after) per axis, not per-axis totals; applying a cropping layer intended for channels_last tensors to channels_first data so the wrong axis is cropped.","solutions":["Reduce the cropping values so that each spatial dim minus the sum of its crop pair stays >= 1: verify input_shape and self.cropping per axis","Check data_format: for channels_first the channel axis is dim 1 and cropping applies to axes 2-4; a wrong data_format makes cropping hit the wrong dimension","Remember cropping is ((d1_crop),(d2_crop),(d3_crop)) with each entry a (head, tail) pair whose sum must be < the corresponding spatial dim","If you need aggressive shrinking, use a pooling/striding layer instead of large crops"],"exampleFix":"# before\nlayer = keras.layers.Cropping3D(cropping=((2,2),(2,2),(2,2)))\nout = layer(tf.random.normal((1, 3, 3, 3, 4)))  # ValueError\n\n# after\nlayer = keras.layers.Cropping3D(cropping=((1,1),(1,1),(1,1)))\nout = layer(tf.random.normal((1, 3, 3, 3, 4)))  # ok: dims become (1,1,1)","handlingStrategy":"validation","validationCode":"def check_cropping3d(input_shape, cropping, data_format='channels_last'):\n    # spatial axes: channels_last -> (1,2,3); channels_first -> (2,3,4)\n    axes = (2, 3, 4) if data_format == 'channels_first' else (1, 2, 3)\n    for ax, pair in zip(axes, cropping):\n        d = input_shape[ax]\n        if d is not None and d - sum(pair) <= 0:\n            raise ValueError(f'crop {pair} too large for axis {ax} (dim {d})')\n    return True","typeGuard":"def is_valid_cropping3d(input_shape, cropping, data_format='channels_last'):\n    axes = (2, 3, 4) if data_format == 'channels_first' else (1, 2, 3)\n    return all(\n        input_shape[ax] is None or input_shape[ax] - sum(pair) > 0\n        for ax, pair in zip(axes, cropping)\n    )","tryCatchPattern":null,"preventionTips":["Unit-test layer construction with the exact input shape from your Input() node","Write cropping configs as explicit ((d1a,d1b),(d2a,d2b),(d3a,d3b)) pairs tied to known dims","Set data_format explicitly instead of relying on global config"],"tags":["keras","cropping3d","shape-validation","reshaping-layer"],"backgroundTag":"invalid-shape-argument","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}