jax-ml/jax · error · NotImplementedError
Found multiple equality constraints with the same left-hand-
Error message
Found multiple equality constraints with the same left-hand-side: {before} What it means
Equality constraints act as normalization rules keyed by their left-hand-side term. Two constraints with the same LHS term (e.g. 'a == b' and 'a == c') would give contradictory definitions, which is not yet supported, hence NotImplementedError.
Source
Thrown at jax/_src/export/shape_poly.py:1085
def _process_explicit_constraint(self, constr: _SymbolicConstraint):
if (diff_const := _DimExpr._to_constant(constr.diff)) is not None:
if ((constr.cmp == Comparator.EQ and diff_const != 0) or
(constr.cmp == Comparator.GEQ and diff_const < 0)):
raise ValueError(f"Unsatisfiable explicit constraint: {constr.debug_str}")
return
if constr.cmp == Comparator.EQ:
if not isinstance(constr.e1, _DimExpr):
raise ValueError("Invalid equality constraint: {e1} == {e2}. "
"The left-hand-side must be of the form `term * coefficient`.")
(before, before_k), *rest = constr.e1._sorted_terms
if rest:
raise ValueError("Invalid equality constraint: {e1} == {e2}. "
"The left-hand-side must be of the form `term * coefficient`.")
after = _ensure_poly(constr.e2, "parse_constraint", constr.e1.scope)
if before in self._normalization_rules:
raise NotImplementedError(
f"Found multiple equality constraints with the same left-hand-side: {before}")
self._normalization_rules[before] = (after, before_k)
# Look for constraints of the form mod(before_e1, before_k2) * 1 == 0
if (before_k == 1 and
isinstance(constr.e2, int) and constr.e2 == 0 and
(before_f := before.to_factor()) and
before_f.operation == _DimFactor.MOD and
(before_k2 := _DimExpr._to_constant(before_f.operands[1])) is not None):
# Add before_k2*floordiv(before_e1, before_k2) == before_e1
k_times_floordiv = _DimExpr._from_term(
_DimTerm.from_operation(
_DimFactor.FLOORDIV, *before_f.operands, scope=constr.e1.scope),
before_k2, scope=constr.e1.scope)
before_e1 = before_f.operands[0]
self._process_explicit_constraint(
_SymbolicConstraint(cmp=Comparator.EQ,
e1=k_times_floordiv, e2=before_e1,
diff=k_times_floordiv - before_e1,View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Express one variable in terms of the other instead of repeating the LHS: keep 'a == b' and write 'b == c' (or substitute)
- Remove the duplicate equality
- Restructure so each symbolic variable is defined by exactly one equality constraint
Example fix
# before
constraints = ('a == b', 'a == c')
# after
constraints = ('a == b', 'b == c') Defensive patterns
Strategy: validation
Validate before calling
lhs_terms = [normalized_lhs(c) for c in eq_constraints] assert len(lhs_terms) == len(set(lhs_terms)), 'duplicate LHS in equality constraints'
Try / catch
try:
scope.add_constraint(c)
except NotImplementedError as e:
if 'same left-hand-side' in str(e): rewrite_via_chain(c) Prevention
- Define each variable exactly once via equality
- Chain definitions (a==b, b==c) instead of repeating an LHS
When it happens
Trigger: Adding constraints 'a*2 == b' and 'a*2 == c' (same normalized LHS term) to one SymbolicScope, including when the second is added later via scope.add_constraint.
Common situations: Dynamically accumulated constraints from multiple modules colliding on the same variable; refactoring that duplicates an existing equality.
Related errors
- The symbolic constraints should be a sequence of strings. Go
- SymbolicScope constraint must be a string: got {repr(c_str)}
- Constraint parsing error: must contain one of '==' or '>=' o
- Unsatisfiable explicit constraint: {constr.debug_str}
- Invalid equality constraint: {e1} == {e2}. The left-hand-sid
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/ad06dfa8cc1035ca.
Report an issue: GitHub.