numpy/numpy · error · ValueError

Output character {char} appeared more than once in the outpu

Error message

Output character {char} appeared more than once in the output.

What it means

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.

Source

Thrown at numpy/_core/einsumfunc.py:611

    # Build output string if does not exist
    if "->" in subscripts:
        input_subscripts, output_subscript = subscripts.split("->")
    else:
        input_subscripts = subscripts
        # Build output subscripts
        tmp_subscripts = subscripts.replace(",", "")
        output_subscript = ""
        for s in sorted(set(tmp_subscripts)):
            if s not in einsum_symbols:
                raise ValueError(f"Character {s} is not a valid symbol.")
            if tmp_subscripts.count(s) == 1:
                output_subscript += s

    # Make sure output subscripts are in the input
    for char in output_subscript:
        if output_subscript.count(char) != 1:
            raise ValueError(f"Output character {char} appeared more than once in "
                             "the output.")
        if char not in input_subscripts:
            raise ValueError(f"Output character {char} did not appear in the input")

    # Make sure number operands is equivalent to the number of terms
    if len(input_subscripts.split(',')) != len(operands):
        raise ValueError("Number of einsum subscripts must be equal to the "
                         "number of operands.")

    return (input_subscripts, output_subscript, operands)


def _einsum_path_dispatcher(*operands, optimize=None, einsum_call=None):
    # NOTE: technically, we should only dispatch on array-like arguments, not
    # subscripts (given as strings). But separating operands into
    # arrays/subscripts is a little tricky/slow (given einsum's two supported
    # signatures), so as a practical shortcut we dispatch on everything.
    # Strings will be ignored for dispatching since they don't define

View on GitHub (pinned to e117b3ca4e)

Solutions

  1. Remove the duplicate label from the output so each appears once.
  2. If you need a repeated axis, reconsider the contraction (einsum cannot duplicate an output axis).
  3. Use np.tile/np.broadcast_to after the contraction to duplicate an axis.

Example fix

// before
np.einsum('ij,jk->iik', a, b)
// after
np.einsum('ij,jk->ik', a, b)
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def safe_einsum(subscripts, *operands):
    if '->' in subscripts:
        out = subscripts.split('->', 1)[1]
        dup = [c for c in set(out) if out.count(c) > 1]
        if dup:
            raise ValueError(f'Output label(s) {dup} repeated in output')
    return np.einsum(subscripts, *operands)

Prevention

When it happens

Trigger: 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.

Common situations: Typos when hand-writing output; templating that appends a label twice; misunderstanding that output labels index axes uniquely.

Related errors


AI-assisted analysis of numpy/numpy@e117b3ca4e (2026-08-07). Data as JSON: /api/errors/29b1cd498be807d3. Report an issue: GitHub.