numpy/numpy · error · ValueError
must be >= 0
Error message
{name} must be >= 0 What it means
Raised by the internal helper _none_or_positive_arg() in numpy/_core/arrayprint.py, which validates numeric keyword arguments to array-printing / float-formatting functions. The contract is: the value may be None (a sentinel meaning 'unset', internally mapped to -1) or a non-negative number; anything strictly negative is rejected. The {name} placeholder carries the offending argument name (e.g. 'precision', 'pad_left', 'exp_digits', 'min_digits') so the message identifies which argument was at fault.
Solutions
- Check the offending named argument before the call: keep it None, or clamp to max(0, value).
- If you intended 'unset', pass None explicitly rather than -1.
- For line/width wrapping use np.set_printoptions(linewidth=-1) — do not reuse that -1 for precision/pad/min_digits.
Example fix
// before np.format_float_scientific(x, precision=width - 1) # width == 0 -> -1 // after np.format_float_scientific(x, precision=max(0, width - 1))
Defensive patterns
Strategy: validation
Validate before calling
def safe_pos_arg(value, name):
if value is None:
return None
if value < 0:
raise ValueError(f"{name} must be >= 0, got {value!r}")
return value
precision = safe_pos_arg(computed_precision, 'precision')
np.format_float_scientific(x, precision=precision) Type guard
def is_none_or_non_negative(v) -> bool:
return v is None or (isinstance(v, (int, float)) and not isinstance(v, bool) and v >= 0) Try / catch
try:
np.format_float_scientific(x, precision=p)
except ValueError as e:
if 'must be >= 0' in str(e):
p = max(0, p) if p is not None else None
np.format_float_scientific(x, precision=p)
else:
raise Prevention
- Treat None as the only 'unset' sentinel for these arguments; never use -1.
- Clamp user-supplied widths with max(0, value) before formatting.
- Do not forward linewidth=-1 from np.set_printoptions into precision-family args.
When it happens
Trigger: Calling np.format_float_scientific / np.format_float_positional (or anything routed through them, such as np.array2string with formatter options) with a strictly negative value for precision, pad_left, pad_right, exp_digits, or min_digits. For example np.format_float_scientific(1.0, precision=-2) or np.format_float_positional(0.5, pad_left=-1).
Common situations: Off-by-one math on a computed width/precision before passing it to a formatter; passing a value that another API returns as -1 on 'unset' without re-checking; confusing the linewidth=-1 sentinel of np.set_printoptions (which means 'no wrapping') with the precision-family arguments, which do NOT accept -1.
Related errors
- all elements of `new_shape` must be non-negative
- argument 1 must be numpy.ndarray, not
- Character is not a valid symbol.
- clip() missing 1 required positional argument: 'a_min'
- clip() missing 1 required positional argument: 'a_max'
AI-assisted analysis of numpy/numpy@44f1f77dd8 (2026-08-11).
Data as JSON: /api/errors/9ded4b07ea6e339b.
Report an issue: GitHub.
Appendix: source
Thrown at numpy/_core/arrayprint.py:982
s = '[' + s[len(hanging_indent):] + ']'
return s
try:
# invoke the recursive part with an initial index and prefix
return recurser(index=(),
hanging_indent=next_line_prefix,
curr_width=line_width)
finally:
# recursive closures have a cyclic reference to themselves, which
# requires gc to collect (gh-10620). To avoid this problem, for
# performance, we break the cycle:
recurser = None
def _none_or_positive_arg(x, name):
if x is None:
return -1
if x < 0:
raise ValueError(f"{name} must be >= 0")
return x
class FloatingFormat:
""" Formatter for subtypes of np.floating """
def __init__(self, data, precision, floatmode, suppress_small, sign=False,
*, legacy=None):
# for backcompatibility, accept bools
if isinstance(sign, bool):
sign = '+' if sign else '-'
self._legacy = legacy
if self._legacy <= 113:
# when not 0d, legacy does not support '-'
if data.shape != () and sign == '-':
sign = ' '
self.floatmode = floatmode
if floatmode == 'unique':View on GitHub (pinned to 44f1f77dd8)