numpy/numpy · error · ValueError

{name} must be >= 0

Error message

{name} must be >= 0

What it means

Raised as ValueError by _none_or_positive_arg (used by FloatingFormat for precision and similar print args) when a non-None argument is negative. Note this surfaces at PRINT time, not at set_printoptions time, because operator.index accepts negative ints — so np.set_printoptions(precision=-1) is stored, and the error fires when an array is actually formatted.

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 e117b3ca4e)

Solutions

  1. Clamp precision to >= 0: max(0, precision)
  2. Use None (or omit) for the default rather than -1
  3. Validate at set_printoptions time: assert precision is None or precision >= 0

Example fix

# before
np.set_printoptions(precision=-1)
print(np.array([1.0]))
# after
np.set_printoptions(precision=0)
print(np.array([1.0]))
Defensive patterns

Strategy: validation

Validate before calling

def safe_precision(p):
    if p is None:
        return None
    if p < 0:
        raise ValueError(f"precision must be >= 0, got {p}")
    return p
# np.set_printoptions(precision=safe_precision(user_p))

Type guard

def is_non_negative_precision(p) -> bool:
    return p is None or (isinstance(p, int) and p >= 0)

Try / catch

try:
    print(arr)  # error surfaces at format time
except ValueError as e:
    if 'must be >= 0' in str(e):
        import numpy as np
        np.set_printoptions(precision=0)
        print(arr)
    else:
        raise

Prevention

When it happens

Trigger: np.set_printoptions(precision=-1) followed by printing any floating array/scalar; code paths constructing FloatingFormat directly with a negative precision.

Common situations: UI controls that return -1 to mean 'unset/default'; computed precision underflowing to negative; confusing None with -1.

Related errors


AI-assisted analysis of numpy/numpy@e117b3ca4e (2026-08-07). Data as JSON: /api/errors/9ded4b07ea6e339b. Report an issue: GitHub.