python/cpython · error · ValueError
Cannot use closefd=False with file name
Error message
Cannot use closefd=False with file name
What it means
Raised by FileIO.__init__ when a path (not an fd) is given together with closefd=False. closefd only has meaning for integer file descriptors — when FileIO opens the file itself from a name, it owns the resulting fd and must be able to close it; refusing closefd=False prevents a leaked fd that nothing else can manage.
Source
Thrown at Lib/_pyio.py:1604
if self._readable and self._writable:
flags |= os.O_RDWR
elif self._readable:
flags |= os.O_RDONLY
else:
flags |= os.O_WRONLY
flags |= getattr(os, 'O_BINARY', 0)
noinherit_flag = (getattr(os, 'O_NOINHERIT', 0) or
getattr(os, 'O_CLOEXEC', 0))
flags |= noinherit_flag
owned_fd = None
try:
if fd < 0:
if not closefd:
raise ValueError('Cannot use closefd=False with file name')
if opener is None:
fd = os.open(file, flags, 0o666)
else:
fd = opener(file, flags)
if not isinstance(fd, int):
raise TypeError('expected integer from opener')
if fd < 0:
# bpo-27066: Raise a ValueError for bad value.
raise ValueError(f'opener returned {fd}')
owned_fd = fd
if not noinherit_flag:
os.set_inheritable(fd, False)
self._closefd = closefd
self._stat_atopen = os.fstat(fd)
try:
if stat.S_ISDIR(self._stat_atopen.st_mode):
raise IsADirectoryError(errno.EISDIR,View on GitHub (pinned to bc6749cc3b)
Solutions
- Drop closefd (or pass closefd=True) when opening by path — True is already the default
- Only use closefd=False when passing an integer fd you want to keep open after the object is closed
- In wrapper APIs, set closefd only for the fd branch: closefd=closefd if isinstance(file, int) else None
Example fix
# before
f = open('data.bin', 'rb', closefd=False) # ValueError
# after
f = open('data.bin', 'rb') # closefd defaults to True for paths
# closefd=False is only valid like this:
g = open(fd, 'rb', closefd=False) Defensive patterns
Strategy: validation
Validate before calling
import os
kwargs = {}
if isinstance(file_arg, int) and not isinstance(file_arg, bool):
kwargs['closefd'] = closefd # only meaningful for real fds
f = open(file_arg, 'rb', **kwargs) Type guard
def closefd_allowed(file):
return isinstance(file, int) and not isinstance(file, bool) Try / catch
try:
f = open(path, 'rb', closefd=closefd)
except ValueError as e:
if 'closefd' in str(e):
f = open(path, 'rb') # retry with default closefd=True
else:
raise Prevention
- Only set closefd when the first argument is an integer fd
- Default closefd=True is correct for path opens — omit the parameter
- Audit helper functions that forward **kwargs into open()
When it happens
Trigger: open(path, 'rb', closefd=False); io.FileIO('data.txt', 'r', closefd=False). Any call where file is a str/bytes/PathLike and closefd is falsy hits this branch because fd < 0 at that point.
Common situations: Copy-pasting closefd=False from code that wrapped an existing fd; wrapping a path-based helper that forwards **kwargs including closefd; library APIs that expose closefd for both fd and path inputs without branching.
Related errors
- negative file descriptor
- Must have exactly one of create/read/write/append mode and a
- opener returned {fd}
- peek on closed file
- truncate on closed file
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/9a07226e89563541.
Report an issue: GitHub.