{"record":{"id":"b75d2a8efba43d78","repo":"keras-team/keras","slug":"self-class-name-was-passed-incompatible","errorCode":null,"errorMessage":"{self.__class__.__name__} was passed incompatible inputs. For input '{x_ref.name}', expected shape {x_ref.shape}, but received instead a tensor with shape {x.shape}.","messagePattern":"(.+?) was passed incompatible inputs\\. For input '(.+?)', expected shape (.+?), but received instead a tensor with shape (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/ops/function.py","lineNumber":239,"sourceCode":"                raise ValueError(\n                    f\"Output with path `{path}` is not connected to `inputs`\"\n                )\n            output_tensors.append(tensor_dict[id(x)])\n\n        return tree.pack_sequence_as(self._outputs_struct, output_tensors)\n\n    def _assert_input_compatibility(self, inputs):\n        try:\n            tree.assert_same_structure(inputs, self._inputs_struct)\n        except ValueError:\n            raise ValueError(\n                \"Function was called with an invalid input structure. \"\n                f\"Expected input structure: {self._inputs_struct}\\n\"\n                f\"Received input structure: {inputs}\"\n            )\n        for x, x_ref in zip(tree.flatten(inputs), self._inputs):\n            if len(x.shape) != len(x_ref.shape):\n                raise ValueError(\n                    f\"{self.__class__.__name__} was passed \"\n                    f\"incompatible inputs. For input '{x_ref.name}', \"\n                    f\"expected shape {x_ref.shape}, but received \"\n                    f\"instead a tensor with shape {x.shape}.\"\n                )\n            for dim, ref_dim in zip(x.shape, x_ref.shape):\n                if ref_dim is not None and dim is not None:\n                    if dim != ref_dim:\n                        raise ValueError(\n                            f\"{self.__class__.__name__} was passed \"\n                            f\"incompatible inputs. For input '{x_ref.name}', \"\n                            f\"expected shape {x_ref.shape}, but received \"\n                            f\"instead a tensor with shape {x.shape}.\"\n                        )\n\n\ndef make_node_key(op, node_index):\n    return f\"{id(op)}_ib-{node_index}\"","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/ops/function.py#L221-L257","documentation":"A Functional (keras.ops.Function) layer built from symbolic inputs validates at call time that each incoming tensor has the same rank (same number of axes) as the KerasTensor input it was traced with. It throws this ValueError when the number of dimensions differs, because the underlying op graph was compiled for a fixed input structure.","triggerScenarios":"Calling a Functional/ops.Function (or a model built via keras.ops on symbolic tensors) with an input whose ndim differs from the traced ndim, e.g. traced with shape (None, 28, 28) but called with (None, 28, 28, 1), or passing a single image (3 dims) where a batch (4 dims) was traced.","commonSituations":"Adding/removing a channels dimension before calling a saved or traced model; switching between channels_last/channels_first pipelines; feeding grayscale vs RGB; reusing a traced preprocessing function on data with an extra batch axis.","solutions":["Compare the 'expected shape' in the message with the 'received shape' and add or remove axes on your input (e.g. x = x[..., None] or np.expand_dims(x, 0)) so both have the same number of dimensions","If the data genuinely changed rank, re-trace/rebuild the function or model with a input matching the new rank","Check for an accidental batch dimension added/removed by your data pipeline (tf.data .batch(), dataset.unbatch(), etc.)"],"exampleFix":"# before\ny = fn(x)  # x.shape=(32, 28, 28) but fn traced with (None, 28, 28, 1)\n\n# after\nx = np.expand_dims(x, -1)  # (32, 28, 28, 1)\ny = fn(x)","handlingStrategy":"validation","validationCode":"rank = len(getattr(x, 'shape', ()))\nif rank != len(fn_input_shape):\n    raise ValueError(f'input rank {rank} != expected {len(fn_input_shape)}')","typeGuard":"def matches_traced_rank(x, ref_shape) -> bool:\n    s = tuple(x.shape)\n    return len(s) == len(ref_shape)","tryCatchPattern":"try:\n    y = fn(x)\nexcept ValueError as e:\n    if 'incompatible inputs' in str(e):\n        x = np.expand_dims(x, -1)\n        y = fn(x)\n    else:\n        raise","preventionTips":["Print model.input_shape once and assert your batch shape matches its rank before calling","Keep one canonical shape-preparation function used by both tracing and inference"],"tags":["keras","shape-mismatch","input-validation","functional"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}