jax-ml/jax · error · TypeError
Encountered unexpected shape dimension {d}
Error message
Encountered unexpected shape dimension {d} What it means
During export, JAX substitutes fake constant dims for symbolic ones when preparing operands for underlying lowering. If a non-constant dimension is not a _DimExpr (e.g. a numpy object, a string, or a dim from a foreign tracer), it cannot be faked and raises TypeError.
Source
Thrown at jax/_src/export/shape_poly.py:1284
opt_einsum.contract_path to parse the specification.
"""
# Replace the polymorphic shapes with some concrete shapes for calling
# into opt_einsum.contract_path, because the latter wants to compute the
# sizes of operands and intermediate results.
fake_ops = []
for operand in operands:
# We replace only array operands
if not hasattr(operand, "dtype"):
fake_ops.append(operand)
else:
shape = np.shape(operand)
def fake_dim(d):
if core.is_constant_dim(d):
return d
else:
if not isinstance(d, _DimExpr):
raise TypeError(f"Encountered unexpected shape dimension {d}")
# It is Ok to replace all polynomials with the same value. We may miss
# here some errors due to non-equal dimensions, but we catch them
# later.
return 8
fake_ops.append(api.ShapeDtypeStruct(tuple(map(fake_dim, shape)),
operand.dtype))
contract_fake_ops, contractions = opt_einsum.contract_path(*fake_ops,
**kwargs)
contract_operands = []
for operand in contract_fake_ops:
idx = tuple(i for i, fake_op in enumerate(fake_ops) if operand is fake_op)
assert len(idx) == 1
contract_operands.append(operands[idx[0]])
return contract_operands, contractions
# To implement shape-constraint checking we use a shape assertion primitive.
# shape_assertion_p.bind(assert_what: bool, *error_message_inputs,View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Ensure all non-constant dims in operand shapes are genuine symbolic dims created by the current export's shape polymorphism
- Materialize shapes to plain ints / re-create inputs as jnp arrays before export
- Align jax/jaxlib versions so dim objects are the internal _DimExpr type
Example fix
# before
x = some_external_array # shape contains object dims
exp = jax.export.export(shapes('n,'))(f)
# after
x = jnp.asarray(x) # normalize to a JAX array with int/symbolic dims
exp = jax.export.export(shapes('n,'))(f) Defensive patterns
Strategy: validation
Validate before calling
def clean_shape(a):
return all(isinstance(d, int) or is_symbolic_dim(d) for d in np.shape(a))
assert clean_shape(x), 'operand has non-int/non-symbolic dims' Type guard
def exportable_operand(a) -> bool:
return isinstance(a, jax.Array) or all(isinstance(d, (int,)) or hasattr(d, '_factors') for d in np.shape(a)) Try / catch
try:
exp = jax.export.export(shapes)(fn)
except TypeError as e:
if 'unexpected shape dimension' in str(e): inputs = [jnp.asarray(i) for i in inputs]; retry() Prevention
- Convert external arrays to jnp arrays before export
- Keep jax/jaxlib versions aligned so dim types match
When it happens
Trigger: An operand's shape contains a non-int, non-_DimExpr dimension object — e.g. a Tracer from another transformation, np.str_, or a custom dim class — while exporting with polymorphic shapes.
Common situations: Composing jax.export with other transforms producing exotic dim objects; passing arrays whose shapes were built by external libs inserting object dims; JAX version incompatibilities in the dim representation.
Related errors
- Encountered dimension variable '{self.var}' that is not appe
- Cannot divide {self} by {divisor}.
- Invalid mixing of symbolic scopes {when}.\nExpected {self_de
- Symbolic dimension {operation_name} not supported for {p}.
- shape polymorphism for Pallas does not support dynamically-s
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/5f657c3968357607.
Report an issue: GitHub.