{"record":{"id":"29b1cd498be807d3","repo":"numpy/numpy","slug":"output-character-char-appeared-more-than-once-in","errorCode":null,"errorMessage":"Output character {char} appeared more than once in the output.","messagePattern":"Output character (.+?) appeared more than once in the output\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"numpy/_core/einsumfunc.py","lineNumber":611,"sourceCode":"\n    # Build output string if does not exist\n    if \"->\" in subscripts:\n        input_subscripts, output_subscript = subscripts.split(\"->\")\n    else:\n        input_subscripts = subscripts\n        # Build output subscripts\n        tmp_subscripts = subscripts.replace(\",\", \"\")\n        output_subscript = \"\"\n        for s in sorted(set(tmp_subscripts)):\n            if s not in einsum_symbols:\n                raise ValueError(f\"Character {s} is not a valid symbol.\")\n            if tmp_subscripts.count(s) == 1:\n                output_subscript += s\n\n    # Make sure output subscripts are in the input\n    for char in output_subscript:\n        if output_subscript.count(char) != 1:\n            raise ValueError(f\"Output character {char} appeared more than once in \"\n                             \"the output.\")\n        if char not in input_subscripts:\n            raise ValueError(f\"Output character {char} did not appear in the input\")\n\n    # Make sure number operands is equivalent to the number of terms\n    if len(input_subscripts.split(',')) != len(operands):\n        raise ValueError(\"Number of einsum subscripts must be equal to the \"\n                         \"number of operands.\")\n\n    return (input_subscripts, output_subscript, operands)\n\n\ndef _einsum_path_dispatcher(*operands, optimize=None, einsum_call=None):\n    # NOTE: technically, we should only dispatch on array-like arguments, not\n    # subscripts (given as strings). But separating operands into\n    # arrays/subscripts is a little tricky/slow (given einsum's two supported\n    # signatures), so as a practical shortcut we dispatch on everything.\n    # Strings will be ignored for dispatching since they don't define","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/numpy/numpy/blob/e117b3ca4edacf581f440dccfd7f3242f0312afa/numpy/_core/einsumfunc.py#L593-L629","documentation":"Raised when an explicit output subscript contains the same label more than once, e.g. 'ij,jk->iik'. Each output position must be a distinct label because einsum's output shape is indexed by unique labels. Guard at einsumfunc.py:610, iterating each output char.","triggerScenarios":"np.einsum('ij,jk->iik', a, b); any '->' clause where a letter repeats. Also reachable from ellipsis expansion that duplicates a label into the output.","commonSituations":"Typos when hand-writing output; templating that appends a label twice; misunderstanding that output labels index axes uniquely.","solutions":["Remove the duplicate label from the output so each appears once.","If you need a repeated axis, reconsider the contraction (einsum cannot duplicate an output axis).","Use np.tile/np.broadcast_to after the contraction to duplicate an axis."],"exampleFix":"// before\nnp.einsum('ij,jk->iik', a, b)\n// after\nnp.einsum('ij,jk->ik', a, b)","handlingStrategy":"validation","validationCode":"import numpy as np\n\ndef safe_einsum(subscripts, *operands):\n    if '->' in subscripts:\n        out = subscripts.split('->', 1)[1]\n        dup = [c for c in set(out) if out.count(c) > 1]\n        if dup:\n            raise ValueError(f'Output label(s) {dup} repeated in output')\n    return np.einsum(subscripts, *operands)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat output labels as a set, not a list, when constructing them.","Add an assertion that len(set(output)) == len(output).","Remember einsum cannot duplicate an output axis; use np.tile after if needed."],"tags":["numpy","einsum","subscripts","output-spec","argument-validation"],"analyzedSha":"e117b3ca4edacf581f440dccfd7f3242f0312afa","analyzedAt":"2026-08-07T01:25:31.049Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}