{"record":{"id":"d5a15e5b92fff37f","repo":"keras-team/keras","slug":"expected-as-input-a-list-tuple-of-2-tensors-recei","errorCode":null,"errorMessage":"Expected as input a list/tuple of 2 tensors. Received input_shape={input_shape}","messagePattern":"Expected as input a list/tuple of 2 tensors\\. Received input_shape=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/preprocessing/hashed_crossing.py","lineNumber":116,"sourceCode":"            allowable_strings=(\"int\", \"one_hot\"),\n            caller_name=self.__class__.__name__,\n            arg_name=\"output_mode\",\n        )\n\n        self.num_bins = num_bins\n        self.output_mode = output_mode\n        self.sparse = sparse\n        self._allow_non_tensor_positional_args = True\n        self._convert_input_args = False\n        self.supports_jit = False\n\n    def compute_output_shape(self, input_shape):\n        if (\n            not len(input_shape) == 2\n            or not isinstance(input_shape[0], tuple)\n            or not isinstance(input_shape[1], tuple)\n        ):\n            raise ValueError(\n                \"Expected as input a list/tuple of 2 tensors. \"\n                f\"Received input_shape={input_shape}\"\n            )\n        if input_shape[0][-1] != input_shape[1][-1]:\n            raise ValueError(\n                \"Expected the two input tensors to have identical shapes. \"\n                f\"Received input_shape={input_shape}\"\n            )\n\n        if not input_shape:\n            if self.output_mode == \"int\":\n                return ()\n            return (self.num_bins,)\n        if self.output_mode == \"int\":\n            return tuple(input_shape[0])\n\n        if self.output_mode == \"one_hot\" and input_shape[0][-1] != 1:\n            return tuple(input_shape[0]) + (self.num_bins,)","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/preprocessing/hashed_crossing.py#L98-L134","documentation":"compute_output_shape expects input_shape to be a list/tuple of exactly two shape-tuples, because HashedCrossing crosses exactly two inputs. Anything else (one shape, three shapes, non-tuple entries) fails validation.","triggerScenarios":"Passing a single tensor instead of a list of two; passing nested lists; Keras Functional model shape inference delivering an unexpected nested structure.","commonSituations":"Passing a single tensor instead of a list of two; passing nested lists; Keras Functional model shape inference delivering an unexpected nested structure.","solutions":["Feed the layer a list/tuple of exactly two tensors: layer([a, b])","When building a Functional model, connect two Input layers to the HashedCrossing layer","To cross more than two features, nest HashedCrossing layers"],"exampleFix":"// before\nlayer = HashedCrossing(num_bins=100)\nout = layer(x)  # single tensor\n// after\nout = layer([a, b])  # exactly two tensors","handlingStrategy":"validation","validationCode":"assert isinstance(input_shape, (list, tuple)) and len(input_shape) == 2 and all(isinstance(s, tuple) for s in input_shape)","typeGuard":"def is_pair_of_shapes(s):\n    return isinstance(s, (list, tuple)) and len(s) == 2 and all(isinstance(i, tuple) for i in s)","tryCatchPattern":"catch ValueError from layer.compute_output_shape()/build and normalize inputs to [x1, x2] of equal shape","preventionTips":["Always feed HashedCrossing a list/tuple of exactly two tensors","Use keras.layers.Input(shape=(1,), name=...) pairs so compute_output_shape sees tuples"],"tags":["keras","hashed-crossing","shape","input-validation"],"backgroundTag":"shape-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}