{"record":{"id":"d892eeb40625b45f","repo":"keras-team/keras","slug":"multiple-target-dimensions-are-not-supported-expe-d892ee","errorCode":null,"errorMessage":"Multiple target dimensions are not supported. Expected: None, int, (int, int), Provided: {axes}","messagePattern":"Multiple target dimensions are not supported\\. Expected: None, int, \\(int, int\\), Provided: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/legacy/backend.py","lineNumber":96,"sourceCode":"    if x_batch_size is not None and y_batch_size is not None:\n        if x_batch_size != y_batch_size:\n            raise ValueError(\n                \"Cannot do batch_dot on inputs \"\n                \"with different batch sizes. \"\n                \"Received inputs with tf.shapes \"\n                f\"{x_shape} and {y_shape}.\"\n            )\n    if isinstance(axes, int):\n        axes = [axes, axes]\n\n    if axes is None:\n        if y_ndim == 2:\n            axes = [x_ndim - 1, y_ndim - 1]\n        else:\n            axes = [x_ndim - 1, y_ndim - 2]\n\n    if py_any(isinstance(a, (list, tuple)) for a in axes):\n        raise ValueError(\n            \"Multiple target dimensions are not supported. \"\n            \"Expected: None, int, (int, int), \"\n            f\"Provided: {axes}\"\n        )\n\n    # if tuple, convert to list.\n    axes = list(axes)\n\n    # convert negative indices.\n    if axes[0] < 0:\n        axes[0] += x_ndim\n    if axes[1] < 0:\n        axes[1] += y_ndim\n\n    # sanity checks\n    if 0 in axes:\n        raise ValueError(\n            \"Cannot perform batch_dot over axis 0. \"","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/legacy/backend.py#L78-L114","documentation":"batch_dot accepts axes as None, an int, or an (int, int) pair; the legacy implementation rejects any axes spec containing a nested list/tuple (e.g. [x_ndim-1, [1, 2]]). Internally ints get normalized to a pair, but per-operand multi-axis targets are not supported by the underlying dot, so a nested sequence triggers this ValueError.","triggerScenarios":"Calling batch_dot(x, y, axes=[[1, 2], [1, 2]]) or any axes spec where either element is itself a list/tuple; porting einsum-style multi-axis contractions from NumPy or tf.tensordot to batch_dot.","commonSituations":"Migrating tf.tensordot or np.einsum code that contracts multiple axes at once; passing axes from a config that used nested lists; older Keras examples that used list-of-lists axes syntax.","solutions":["Contract one axis per operand: pass a flat pair like axes=(1, 1) and reshape beforehand to fold extra axes together","For genuine multi-axis contraction, use tf.tensordot or keras.ops.einsum instead of batch_dot","Normalize axes input to an int or (int, int) before calling"],"exampleFix":"# before\nout = keras.ops.batch_dot(x, y, axes=[[1, 2], [1, 2]])\n\n# after\nx_flat = keras.ops.reshape(x, (-1, d1 * d2))\ny_flat = keras.ops.reshape(y, (-1, d1 * d2))\nout = keras.ops.batch_dot(x_flat, y_flat, axes=(1, 1))","handlingStrategy":"validation","validationCode":"axes = (axes, axes) if isinstance(axes, int) else tuple(axes)\nassert all(isinstance(a, int) for a in axes), f'axes must be int or (int, int), got {axes}'\nout = keras.ops.batch_dot(x, y, axes=axes)","typeGuard":"def valid_batch_dot_axes(axes) -> bool:\n    if axes is None or isinstance(axes, int):\n        return True\n    if isinstance(axes, (tuple, list)) and len(axes) == 2:\n        return all(isinstance(a, int) for a in axes)\n    return False","tryCatchPattern":null,"preventionTips":["Pass axes as an int or flat (int, int) pair only","Use einsum or tensordot for multi-axis contractions"],"tags":["keras","batch-dot","axes-validation","legacy-backend"],"backgroundTag":"invalid-argument-value","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}