RustPython/RustPython · info · ValueError

unknown mode: %r

Error message

unknown mode: %r

What it means

ValueError from the final else-branch of _pyio.open() after buffer-type selection - it fires when the mode is neither updating ('+'), nor creating/writing/appending, nor reading. Because the earlier check at line 221 already guarantees exactly one of x/r/w/a is present, this branch is effectively unreachable defensive code inherited from CPython; seeing it means the mode string was mutated concurrently, the module was monkey-patched, or the interpreter itself is misbehaving.

Source

Thrown at Lib/_pyio.py:261

        if buffering == 1 or buffering < 0 and raw._isatty_open_only():
            buffering = -1
            line_buffering = True
        if buffering < 0:
            buffering = max(min(raw._blksize, 8192 * 1024), DEFAULT_BUFFER_SIZE)
        if buffering < 0:
            raise ValueError("invalid buffering size")
        if buffering == 0:
            if binary:
                return result
            raise ValueError("can't have unbuffered text I/O")
        if updating:
            buffer = BufferedRandom(raw, buffering)
        elif creating or writing or appending:
            buffer = BufferedWriter(raw, buffering)
        elif reading:
            buffer = BufferedReader(raw, buffering)
        else:
            raise ValueError("unknown mode: %r" % mode)
        result = buffer
        if binary:
            return result
        encoding = text_encoding(encoding)
        text = TextIOWrapper(buffer, encoding, errors, newline, line_buffering)
        result = text
        text.mode = mode
        return result
    except:
        result.close()
        raise

# Define a default pure-Python implementation for open_code()
# that does not allow hooks. Warn on first use. Defined for tests.
def _open_code_with_warning(path):
    """Opens the provided file with mode ``'rb'``. This function
    should be used when the intent is to treat the contents as
    executable code.

View on GitHub (pinned to aaeab4f754)

Solutions

  1. Treat it as an interpreter/framework bug: report to the runtime used (CPython or the port) with a minimal reproducer
  2. Audit the process for monkey-patching of _pyio.open or of stream classes
  3. Retry with an explicit canonical mode string ('r', 'rb', ...) to rule out mode corruption
Defensive patterns

Strategy: try-catch

Try / catch

try:
    f = open(path, mode)
except ValueError as e:
    if 'unknown mode' in str(e):
        log.exception('mode dispatch failure - interpreter-level bug')
    raise                              # not recoverable at the call site

Prevention

When it happens

Trigger: Not producible through the public API under normal execution; would require mutating the mode between validation and dispatch (hostile monkey-patching of _pyio.open, or a divergent port such as an embedded interpreter).

Common situations: Essentially none in practice; reported occurrences are usually misattributed line numbers from a different open() implementation (e.g. a patched, embedded, or ported interpreter like RustPython drift).

Related errors


AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17). Data as JSON: /api/errors/ade1221c81b58e8e. Report an issue: GitHub.