juicedata/juicefs · error · ValueError

I/O operation on closed file.

Error message

I/O operation on closed file.

What it means

_check_closed() raises ValueError('I/O operation on closed file.') whenever any I/O method (read, write, seek, tell, truncate, readlines) is used after close() has run (explicitly or via __del__/context exit).

Source

Thrown at sdk/python/juicefs/juicefs/juicefs.py:607

    def flush(self):
        return

    def fsync(self):
        self.lib.jfs_fsync(c_int64(_tid()), c_int32(self.fd))

    def close(self):
        if self.closed:
            return
        self.lib.jfs_close(c_int64(_tid()), c_int32(self.fd))
        self.closed = True

    def __del__(self):
        self.close()

    def _check_closed(self):
        if self.closed:
            raise ValueError('I/O operation on closed file.')

    def readline(self): # TODO: add parameter `size=-1`
        """Read until newline or EOF."""
        ls = self.readlines(1)
        if ls:
            return ls[0]
        return b''

    def xreadlines(self):
        return self

    def readlines(self, hint=-1):
        """Return a list of lines from the stream."""
        self._check_closed()
        if hint == -1:
            data = self.read(-1)
        else:
            rs = []

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Reopen the file with juicefs.open() before further I/O
  2. Move the I/O inside the with-block that owns the file
  3. Check f.closed before operating on the handle

Example fix

// before
f = juicefs.open(p, 'rb')
f.close()
data = f.read()
// after
with juicefs.open(p, 'rb') as f:
    data = f.read()
if f.closed:
    f = juicefs.open(p, 'rb')
data = f.read()
Defensive patterns

Strategy: try-catch

Validate before calling

if f.closed:
    f = juicefs.open(f.path, f.mode)

Try / catch

try:
    data = f.read()
except ValueError as e:
    if 'closed file' in str(e):
        f = juicefs.open(path, 'rb')
        data = f.read()
    else:
        raise

Prevention

When it happens

Trigger: Calling f.read() after f.close(); using the file object outside a with-block after it was garbage collected; keeping a reference past a with statement and re-reading; double-close followed by use.

Common situations: Storing file handles in long-lived objects/dicts and reusing them later; functions returning closed handles; exception paths that close the file then retry reads.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/86705ecfafd67d32. Report an issue: GitHub.