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 defineView on GitHub (pinned to e117b3ca4e)
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.
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
- 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.
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
- Output character {char} did not appear in the input
- Character {s} is not a valid symbol.
- For this input type lists must contain either int or Ellipsi
- Subscripts can only contain one '->'.
- Invalid Ellipses.
AI-assisted analysis of numpy/numpy@e117b3ca4e (2026-08-07).
Data as JSON: /api/errors/29b1cd498be807d3.
Report an issue: GitHub.