jax-ml/jax · error · ValueError
size must be a positive integer; got {size=}
Error message
size must be a positive integer; got {size=} What it means
Raised by the Nonzero HiJAX primitive when the static size argument is a negative integer. size declares how many nonzero entries to return (with padding), so it must be non-negative. Symbolic dimensions skip this check, but concrete negative sizes fail immediately.
Source
Thrown at jax/_src/numpy/hijax.py:201
"""HiJAX primitive for nonzero."""
size: int
axes: tuple[int, ...]
out_dtype: np.dtype
def __init__(
self,
a_aval: core.ShapedArray,
*fill_value_avals: core.ShapedArray,
size: int,
axes: tuple[int, ...],
out_dtype: np.dtype):
if core.is_symbolic_dim(size):
pass
else:
size = operator.index(size)
if size < 0:
raise ValueError(f"size must be a positive integer; got {size=}")
if not dtypes.issubdtype(out_dtype, np.integer):
raise ValueError(f"out_dtype must be integer typed; got {out_dtype=}")
if not all(0 <= ax < a_aval.ndim for ax in axes):
raise ValueError(f"axes out of range for array with {a_aval.ndim} dimensions: {axes=}")
if len(axes) != len(set(axes)):
raise ValueError(f"duplicate axes are not allowed: {axes=}")
if fill_value_avals and len(fill_value_avals) != len(axes):
raise ValueError(f"Expected {len(axes)} fill values, got {len(fill_value_avals)}")
if any(fv.dtype != out_dtype for fv in fill_value_avals):
raise ValueError(f"Expected fill values to have dtype {out_dtype}, got {fill_value_avals}")
batch_shape = tuple(
s for i, s in enumerate(a_aval.shape) if i not in axes
)
for fv_aval in fill_value_avals:
try:
broadcasted = lax.broadcast_shapes(fv_aval.shape, batch_shape)
except ValueError as e:
raise ValueError(View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Clamp the computed size: size = max(0, computed_size)
- Pass an explicit non-negative upper bound on the number of nonzeros
Example fix
# before idx = nonzero(a, size=len(a) - k) # negative when k > len(a) # after idx = nonzero(a, size=max(0, len(a) - k))
Defensive patterns
Strategy: validation
Validate before calling
size = operator.index(size) assert size >= 0, size
Type guard
def valid_size(n) -> bool:
return isinstance(n, int) and n >= 0 Prevention
- Clamp computed sizes: size = max(0, n)
- Treat size as a static compile-time constant in JAX, not a tensor
When it happens
Trigger: Calling jax.numpy nonzero(..., size=-1) or passing a computed size that went negative (e.g. size = n_true - margin without clamping).
Common situations: Estimating size from a data-dependent count that can be negative in edge batches; off-by-one arithmetic on an upper bound.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- out_dtype must be integer typed; got {out_dtype=}
- axes out of range for array with {a_aval.ndim} dimensions:
- duplicate axes are not allowed: {axes=}
- Expected {len(axes)} fill values, got {len(fill_value_avals)
- fill_value tuple must have length equal to number of axes ({
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/9d575c0b3854e665.
Report an issue: GitHub.