{"record":{"id":"235d6fca9665604c","repo":"keras-team/keras","slug":"all-axis-values-must-be-in-the-range-ndim-ndi-235d6f","errorCode":null,"errorMessage":"All `axis` values must be in the range [-ndim, ndim). Received inputs with ndim={ndim}, while axis={self.axis}","messagePattern":"All `axis` values must be in the range \\[-ndim, ndim\\)\\. Received inputs with ndim=(.+?), while axis=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/preprocessing/normalization.py","lineNumber":162,"sourceCode":"                    f\"variance shape {np.shape(variance)}\"\n                )\n            # Verify mean rank <= number of axes.\n            if len(np.shape(mean)) > len(self.axis):\n                raise ValueError(\n                    \"The rank of `mean` must be less than or equal to the \"\n                    f\"number of axes ({len(self.axis)}). Received: \"\n                    f\"mean shape {np.shape(mean)} for axis {self.axis}\"\n                )\n\n    def build(self, input_shape):\n        if input_shape is None:\n            return\n\n        ndim = len(input_shape)\n        self._build_input_shape = input_shape\n\n        if any(a < -ndim or a >= ndim for a in self.axis):\n            raise ValueError(\n                \"All `axis` values must be in the range [-ndim, ndim). \"\n                f\"Received inputs with ndim={ndim}, while axis={self.axis}\"\n            )\n\n        # Axes to be kept, replacing negative values with positive equivalents.\n        # Sorted to avoid transposing axes.\n        self._keep_axis = tuple(\n            sorted([d if d >= 0 else d + ndim for d in self.axis])\n        )\n        # All axes to be kept should have known shape.\n        for d in self._keep_axis:\n            if input_shape[d] is None:\n                raise ValueError(\n                    \"All `axis` values to be kept must have a known shape. \"\n                    f\"Received axis={self.axis}, \"\n                    f\"inputs.shape={input_shape}, \"\n                    f\"with unknown axis at index {d}\"\n                )","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/preprocessing/normalization.py#L144-L180","documentation":"During build(), Normalization validates that every entry of self.axis lies in [-ndim, ndim) of the actual input. Values outside that half-open range are rejected because no such axis exists to normalize.","triggerScenarios":"Normalization(axis=2) receiving 2-D input (batch, features); axis=-3 on 2-D input; a saved layer whose axis fit the training data but not the new input shape.","commonSituations":"Reusing a layer across models with different input ranks (sequence vs single sample); off-by-one axis values copied from another layer's config.","solutions":["Set axis to a valid index for your input rank, commonly -1 (last/feature axis)","Ensure the input has the expected rank, e.g. expand dims for a missing channel axis","Sanity-check: assert -ndim <= axis < ndim before building"],"exampleFix":"// before\nlayer = Normalization(axis=2)\nlayer.build((None, 10))  # ValueError\n// after\nlayer = Normalization(axis=-1)\nlayer.build((None, 10))","handlingStrategy":"validation","validationCode":"ndim = len(input_shape)\nassert all(-ndim <= a < ndim for a in axis_list), 'axis out of range'","typeGuard":"def axis_ok(axis, ndim): return all(-ndim <= a < ndim for a in axis)","tryCatchPattern":null,"preventionTips":["Prefer axis=-1 to avoid rank math","Assert input rank matches expectations before build"],"tags":["keras","normalization","axis-validation","build"],"backgroundTag":"invalid-axis-index","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}