jax-ml/jax · error · ValueError
Passing complex start/stop/step to jnp.arange is no longer s
Error message
Passing complex start/stop/step to jnp.arange is no longer supported starting in JAX v0.10.0.
What it means
Starting with JAX v0.10.0, complex-valued start/stop/step arguments to jnp.arange are rejected with this ValueError. Complex arange has ambiguous semantics and poor hardware support, so JAX removed it; users must construct complex ranges manually from real ones.
Source
Thrown at jax/_src/numpy/lax_numpy.py:5971
# Ensure start/stop/step are scalars
for name, val in [(start_name, start), ("stop", stop), ("step", step)]:
if val is not None and np.ndim(val) != 0:
raise ValueError(f"jax.numpy.arange: arguments must be scalars; got {name}={val}")
# Handle symbolic dimensions
if any(core.is_symbolic_dim(v) for v in (start, stop, step)):
if stop is None:
start, stop = 0, start
if step is None:
step = 1
return _arange_dynamic(start, stop, step, dtype or dtypes.default_int_dtype())
if dtype is None:
dtype = dtypes.result_type(start, *(x for x in [stop, step] if x is not None))
dtype = dtypes.jax_dtype(dtype)
if iscomplexobj(start) or iscomplexobj(stop) or iscomplexobj(step):
raise ValueError(
"Passing complex start/stop/step to jnp.arange is no longer supported"
" starting in JAX v0.10.0.")
if stop is None:
start, stop = 0, start
if step is not None:
# arange(N, M, K)
if (dtype is not None and
dtypes.issubdtype(dtype, np.floating) and
dtypes.finfo(dtype).bits < 32):
working_dtype = np.dtype('float32')
else:
working_dtype = dtype
size = max(0, int(np.ceil((stop - start) / step)))
return lax.convert_element_type(
lax.add(lax.convert_element_type(start, working_dtype),
lax.mul(lax.convert_element_type(step, working_dtype),View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Build a real arange and convert: (jnp.arange(n) * step).astype(complex) or jnp.arange(n) * (1+2j)
- Use jnp.linspace for complex endpoints: jnp.linspace(0, 5+0j, n) which supports complex dtypes
- Generate complex values via explicit real+imag construction
Example fix
// before z = jnp.arange(0, 10, 1+0.5j) // after z = jnp.arange(0, 10) * (1+0.5j)
Defensive patterns
Strategy: validation
Validate before calling
import jax.numpy as jnp assert not jnp.iscomplexobj(start) and not jnp.iscomplexobj(stop) and not jnp.iscomplexobj(step)
Type guard
def is_real_scalar(v) -> bool:
return np.ndim(v) == 0 and not np.iscomplexobj(v) Prevention
- Pin JAX version when upgrading codebases using complex arange
- Construct complex ranges as real_range * complex_step
When it happens
Trigger: jnp.arange(0, 5, 1+2j), or passing complex-typed start/stop computed from complex dtype promotions, e.g. arange over a complex endpoint after result_type of a complex array.
Common situations: Upgrading JAX past v0.10.0 breaks previously-working (or silently odd) complex arange calls; complex-valued signal generation code (phasors, complex exponent grids) that used arange directly.
Related errors
- Effects not supported in AD of `checkpoint`/`remat`: {disall
- lax.bitcast_convert_type does not support bool or complex va
- jax.numpy.arange: arguments must be scalars; got {name}={val
- In arange with non-constant arguments all of start, stop, an
- arange has step == 0
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/793c8760526ac7ef.
Report an issue: GitHub.