{"record":{"id":"9ded4b07ea6e339b","repo":"numpy/numpy","slug":"name-must-be-0","errorCode":null,"errorMessage":"{name} must be >= 0","messagePattern":"(.+?) must be >= 0","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"numpy/_core/arrayprint.py","lineNumber":982,"sourceCode":"        s = '[' + s[len(hanging_indent):] + ']'\n        return s\n\n    try:\n        # invoke the recursive part with an initial index and prefix\n        return recurser(index=(),\n                        hanging_indent=next_line_prefix,\n                        curr_width=line_width)\n    finally:\n        # recursive closures have a cyclic reference to themselves, which\n        # requires gc to collect (gh-10620). To avoid this problem, for\n        # performance, we break the cycle:\n        recurser = None\n\ndef _none_or_positive_arg(x, name):\n    if x is None:\n        return -1\n    if x < 0:\n        raise ValueError(f\"{name} must be >= 0\")\n    return x\n\nclass FloatingFormat:\n    \"\"\" Formatter for subtypes of np.floating \"\"\"\n    def __init__(self, data, precision, floatmode, suppress_small, sign=False,\n                 *, legacy=None):\n        # for backcompatibility, accept bools\n        if isinstance(sign, bool):\n            sign = '+' if sign else '-'\n\n        self._legacy = legacy\n        if self._legacy <= 113:\n            # when not 0d, legacy does not support '-'\n            if data.shape != () and sign == '-':\n                sign = ' '\n\n        self.floatmode = floatmode\n        if floatmode == 'unique':","sourceCodeStart":964,"sourceCodeEnd":1000,"githubUrl":"https://github.com/numpy/numpy/blob/e117b3ca4edacf581f440dccfd7f3242f0312afa/numpy/_core/arrayprint.py#L964-L1000","documentation":"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.","triggerScenarios":"np.set_printoptions(precision=-1) followed by printing any floating array/scalar; code paths constructing FloatingFormat directly with a negative precision.","commonSituations":"UI controls that return -1 to mean 'unset/default'; computed precision underflowing to negative; confusing None with -1.","solutions":["Clamp precision to >= 0: max(0, precision)","Use None (or omit) for the default rather than -1","Validate at set_printoptions time: assert precision is None or precision >= 0"],"exampleFix":"# before\nnp.set_printoptions(precision=-1)\nprint(np.array([1.0]))\n# after\nnp.set_printoptions(precision=0)\nprint(np.array([1.0]))","handlingStrategy":"validation","validationCode":"def safe_precision(p):\n    if p is None:\n        return None\n    if p < 0:\n        raise ValueError(f\"precision must be >= 0, got {p}\")\n    return p\n# np.set_printoptions(precision=safe_precision(user_p))","typeGuard":"def is_non_negative_precision(p) -> bool:\n    return p is None or (isinstance(p, int) and p >= 0)","tryCatchPattern":"try:\n    print(arr)  # error surfaces at format time\nexcept ValueError as e:\n    if 'must be >= 0' in str(e):\n        import numpy as np\n        np.set_printoptions(precision=0)\n        print(arr)\n    else:\n        raise","preventionTips":["Use None for default precision, not -1","Clamp UI/config precision to max(0, value)","Validate precision at set_printoptions time since the error fires later at print"],"tags":["printing","precision","validation"],"analyzedSha":"e117b3ca4edacf581f440dccfd7f3242f0312afa","analyzedAt":"2026-08-07T01:25:31.049Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}