jax-ml/jax · error · ValueError

arange has step == 0

Error message

arange has step == 0

What it means

In jnp.arange's dynamic path, a step that statically evaluates to exactly zero raises this ValueError because an arange with zero step has infinite/undefined length. The check must resolve statically; a symbolic step whose sign can't be decided instead raises InconclusiveDimensionOperation.

Source

Thrown at jax/_src/numpy/lax_numpy.py:6014

    return lax.broadcasted_iota(dtype, (size,), 0, out_sharding=out_sharding)
  else:
    # arange(N, M)
    size = max(0, int(np.ceil(stop - start)))
    return lax.add(lax.convert_element_type(start, dtype),
                    lax.broadcasted_iota(dtype, (size,), 0, out_sharding=out_sharding))

def _arange_dynamic(
    start: DimSize, stop: DimSize, step: DimSize, dtype: DTypeLike) -> Array:
  # Here if at least one of start, stop, step are dynamic.
  if any(not core.is_dim(v) for v in (start, stop, step)):
    raise ValueError(
        "In arange with non-constant arguments all of start, stop, and step "
        f"must be either dimension expressions or integers: start={start}, "
        f"stop={stop}, step={step}")
  # Must resolve statically if step is {<0, ==0, >0}
  try:
    if step == 0:
      raise ValueError("arange has step == 0")
    step_gt_0 = (step > 0)
  except core.InconclusiveDimensionOperation as e:
    raise core.InconclusiveDimensionOperation(
        f"In arange with non-constant arguments the step ({step}) must " +
        f"be resolved statically if it is > 0 or < 0.\nDetails: {e}")
  gap = step if step_gt_0 else - step
  distance = (stop - start) if step_gt_0 else (start - stop)
  size = core.max_dim(0, distance + gap - 1) // gap
  return (array(start, dtype=dtype) +
          array(step, dtype=dtype) * lax.iota(dtype, size))


@export
def meshgrid(*xi: ArrayLike, copy: bool = True, sparse: bool = False,
             indexing: str = 'xy') -> tuple[Array, ...]:
  """Construct N-dimensional grid arrays from N 1-dimensional vectors.

  JAX implementation of :func:`numpy.meshgrid`.

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Guard the step before calling: if step == 0: raise/handle, else arange
  2. Use a small nonzero epsilon if a degenerate range is intended: step or 1e-9 (with awareness of length explosion)
  3. Fix the step computation so it cannot collapse to zero (validate end != start)

Example fix

// before
xs = jnp.arange(start, stop, stop - start * 2)  # zero when stop == 0... e.g. step=0
// after
step = stop - start
xs = jnp.arange(start, stop, step) if step != 0 else jnp.array([start])
Defensive patterns

Strategy: validation

Validate before calling

if step == 0:
    raise ValueError('zero step')
xs = jnp.arange(start, stop, step)

Try / catch

try:
    xs = jnp.arange(start, stop, step)
except ValueError as e:
    if 'step == 0' in str(e):
        xs = jnp.array([start])
    else:
        raise

Prevention

When it happens

Trigger: jnp.arange(0, 10, 0) directly, or step computed as a difference that is zero, e.g. step = stop - stop, or step = arr.shape[0] - arr.shape[0] in dynamic-shape code.

Common situations: Step derived from user configuration where an extreme setting collapses it to zero (step = 1/n with overflow, or delta = end - start where end == start); adaptive-sampling loops passing a zero increment.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/1e4edea04b8a2266. Report an issue: GitHub.