jax-ml/jax · error · InconclusiveDimensionOperation
Symbolic dimension '{self}' used in a context that requires
Error message
Symbolic dimension '{self}' used in a context that requires a constant What it means
Python calls int(x) when an object is used where a plain integer is required (e.g. range(dim), list slicing, building shapes for non-JAX APIs). A symbolic dimension has no known integer value, so it cannot be converted, raising InconclusiveDimensionOperation.
Source
Thrown at jax/_src/export/shape_poly.py:820
def __rmod__(self, dividend):
if isinstance(dividend, core.Tracer) or not _convertible_to_poly(dividend):
return self.__jax_array__().__rmod__(dividend)
return _ensure_poly(dividend, "mod", self.scope).__mod__(self)
def __divmod__(self, divisor):
if isinstance(divisor, core.Tracer) or not _convertible_to_poly(divisor):
return self.__jax_array__().__divmod__(divisor)
return self._divmod(divisor)
def __rdivmod__(self, dividend):
if isinstance(dividend, core.Tracer) or not _convertible_to_poly(dividend):
return self.__jax_array__().__rdivmod__(dividend)
return _ensure_poly(dividend, "divmod", self.scope).__divmod__(self)
def __int__(self):
if (c := _DimExpr._to_constant(self)) is not None:
return c
raise InconclusiveDimensionOperation(f"Symbolic dimension '{self}' used in a context that requires a constant")
# We must overload __eq__ and __ne__, or else we get unsound defaults.
def __eq__(self, other: Any) -> bool:
if isinstance(other, type(self)):
if self.scope is not other.scope:
return False
elif not core.is_constant_dim(other):
return False
# Equality is used very frequently because expressions are cached. We could
# implement a more precise version based on `(self - other).bounds() = (0, 0)`
# but that would be too expensive. It would also have the unfortunate drawback
# that we cannot then cache `e.bounds()` because hashing invokes equality
# which would lead to infinite recursion.
diff = self - other
# We look for `self - other == k`, and we rely on the fact that when we
# normalize _DimExpr that represent integers as ints.View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Replace Python constructs with JAX equivalents (lax.iota / jnp.arange instead of range; jnp.zeros instead of np.zeros)
- Move the int() usage outside the traced function or make that dimension concrete
- Use jnp operations that accept traced values instead of host-side ints
Example fix
# before for i in range(n): acc += x[i] # n symbolic # after acc = jnp.sum(x, axis=0) # or use vmap/lax.fori_loop with traced bounds
Defensive patterns
Strategy: type-guard
Validate before calling
from jax._src.export.shape_poly import _DimExpr, InconclusiveDimensionOperation if isinstance(d, _DimExpr): use_jnp_ops(d) # never int(d)
Type guard
def needs_constant(d) -> bool:
return isinstance(d, (int,)) and not hasattr(d, '_factors') Try / catch
from jax._src.export import shape_poly
try:
n = int(dim)
except shape_poly.InconclusiveDimensionOperation:
n = None # switch to jnp.arange/lax equivalents Prevention
- Replace range()/np.* host calls with jnp./lax. equivalents in traced code
- Audit for int(dim), slicing with symbolic bounds before export
When it happens
Trigger: range(symbolic_dim), np.zeros((dim,)), or any int(dim)/indexing use while tracing with polymorphic shapes under jax.export.
Common situations: Porting code to shape-polymorphic export where a batch dimension is used in Python-level loops, Python slicing with symbolic bounds, or passed to numpy/stdlib functions.
Related errors
- The unsafe_buffer_pointer() method was called on {self._erro
- Triggering __jax_array__() during abstractification is no lo
- Cannot interpret value of type {typ} as an abstract array; i
- Encountered dimension variable '{self.var}' that is not appe
- Cannot divide {self} by {divisor}.
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/33d3c9aec68471de.
Report an issue: GitHub.