{"record":{"id":"a4adcbbc6c4ba82a","repo":"python/cpython","slug":"negative-file-descriptor","errorCode":null,"errorMessage":"negative file descriptor","messagePattern":"negative file descriptor","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pyio.py","lineNumber":1555,"sourceCode":"            # Have to close the existing file first.\n            self._stat_atopen = None\n            try:\n                if self._closefd:\n                    os.close(self._fd)\n            finally:\n                self._fd = -1\n\n        if isinstance(file, float):\n            raise TypeError('integer argument expected, got float')\n        if isinstance(file, int):\n            if isinstance(file, bool):\n                import warnings\n                warnings.warn(\"bool is used as a file descriptor\",\n                              RuntimeWarning, stacklevel=2)\n                file = int(file)\n            fd = file\n            if fd < 0:\n                raise ValueError('negative file descriptor')\n        else:\n            fd = -1\n\n        if not isinstance(mode, str):\n            raise TypeError('invalid mode: %s' % (mode,))\n        if not set(mode) <= set('xrwab+'):\n            raise ValueError('invalid mode: %s' % (mode,))\n        if sum(c in 'rwax' for c in mode) != 1 or mode.count('+') > 1:\n            raise ValueError('Must have exactly one of create/read/write/append '\n                             'mode and at most one plus')\n\n        if 'x' in mode:\n            self._created = True\n            self._writable = True\n            flags = os.O_EXCL | os.O_CREAT\n        elif 'r' in mode:\n            self._readable = True\n            flags = 0","sourceCodeStart":1537,"sourceCodeEnd":1573,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyio.py#L1537-L1573","documentation":"Raised by FileIO.__init__ when an integer file argument is less than zero. After the float rejection and the bool warning/conversion, an int fd is accepted only if it is >= 0; negative integers can never name an open file, so they fail fast before os.fstat is attempted.","triggerScenarios":"open(-1, 'rb'); passing a sentinel like -1 that an earlier os.dup()/socket() failure returned, or an uninitialized fd variable defaulting to a negative sentinel; index arithmetic that produced a negative value used as an fd.","commonSituations":"Code that stores fd = -1 as 'no fd yet' and later passes it to open() without checking whether the real fd was ever assigned; error paths where os.open returned and the -1 default leaked through; porting C code that used -1 sentinels.","solutions":["Check the variable for the sentinel before using it as an fd: if fd < 0: raise/handle","Initialize fd variables to None rather than -1 so misuse fails with a clearer error","Ensure the earlier os.open/socket call actually succeeded and its return value (which raises on failure rather than returning -1 in Python) is what gets passed"],"exampleFix":"# before\nfd = -1  # sentinel\n... \nf = open(fd, 'rb')  # ValueError: negative file descriptor\n\n# after\nif fd is None or fd < 0:\n    raise RuntimeError('file descriptor was never opened')\nf = open(fd, 'rb')","handlingStrategy":"validation","validationCode":"if isinstance(fd, bool) or not isinstance(fd, int):\n    raise TypeError('fd must be an int')\nif fd < 0:\n    raise ValueError('negative file descriptor')\nf = open(fd, 'rb')","typeGuard":"def is_valid_fd(fd):\n    return isinstance(fd, int) and not isinstance(fd, bool) and fd >= 0","tryCatchPattern":"try:\n    f = open(fd, 'rb')\nexcept ValueError as e:\n    if 'negative' in str(e):\n        fd = acquire_fd()  # actually open/accept it\n        f = open(fd, 'rb')\n    else:\n        raise","preventionTips":["Initialize fd variables to None, never -1","Check fd validity right after whatever produced it, before storing it","Treat a negative fd as a bug in the producing code, not an input to handle"],"tags":["python","io","file-io","file-descriptor","valueerror"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}