{"record":{"id":"2bd9f3b56456f6fe","repo":"python/cpython","slug":"binary-mode-doesn-t-take-an-errors-argument","errorCode":null,"errorMessage":"binary mode doesn't take an errors argument","messagePattern":"binary mode doesn't take an errors argument","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pyio.py","lineNumber":225,"sourceCode":"    if modes - set(\"axrwb+t\") or len(mode) > len(modes):\n        raise ValueError(\"invalid mode: %r\" % mode)\n    creating = \"x\" in modes\n    reading = \"r\" in modes\n    writing = \"w\" in modes\n    appending = \"a\" in modes\n    updating = \"+\" in modes\n    text = \"t\" in modes\n    binary = \"b\" in modes\n    if text and binary:\n        raise ValueError(\"can't have text and binary mode at once\")\n    if creating + reading + writing + appending > 1:\n        raise ValueError(\"can't have read/write/append mode at once\")\n    if not (creating or reading or writing or appending):\n        raise ValueError(\"must have exactly one of read/write/append mode\")\n    if binary and encoding is not None:\n        raise ValueError(\"binary mode doesn't take an encoding argument\")\n    if binary and errors is not None:\n        raise ValueError(\"binary mode doesn't take an errors argument\")\n    if binary and newline is not None:\n        raise ValueError(\"binary mode doesn't take a newline argument\")\n    if binary and buffering == 1:\n        import warnings\n        warnings.warn(\"line buffering (buffering=1) isn't supported in binary \"\n                      \"mode, the default buffer size will be used\",\n                      RuntimeWarning, 2)\n    raw = FileIO(file,\n                 (creating and \"x\" or \"\") +\n                 (reading and \"r\" or \"\") +\n                 (writing and \"w\" or \"\") +\n                 (appending and \"a\" or \"\") +\n                 (updating and \"+\" or \"\"),\n                 closefd, opener=opener)\n    result = raw\n    try:\n        line_buffering = False\n        if buffering == 1 or buffering < 0 and raw._isatty_open_only():","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyio.py#L207-L243","documentation":"Raised by io.open() as a ValueError when binary mode ('b') is combined with a non-None errors argument. The errors handler governs text encode/decode failures; a binary stream performs no codec work, so the argument is rejected.","triggerScenarios":"open('f.bin', 'wb', errors='replace'), or wrappers that unconditionally forward errors=... while the mode is binary. Often appears together with error 170 when both encoding and errors are threaded through every call.","commonSituations":"Shared open helpers with errors='replace' defaults; migrating a text-mode call to binary for speed while keeping the error-handler kwarg; copy-pasted open() lines edited from 'r' to 'rb' but leaving the kwargs.","solutions":["Remove the errors argument for binary opens.","Conditionally build kwargs: include errors (and encoding) only when 'b' not in mode.","If you wanted lenient decoding, you are handling text — use text mode with errors='replace'."],"exampleFix":"// before\nwith open(path, 'rb', errors='ignore') as f:   # ValueError\n    data = f.read()\n\n// after\nwith open(path, 'rb') as f:\n    data = f.read()\n# or, if text was intended:\nwith open(path, 'r', encoding='utf-8', errors='ignore') as f:\n    text = f.read()","handlingStrategy":"validation","validationCode":"def open_any(path, mode='r', encoding=None, errors=None, newline=None):\n    if 'b' in mode:\n        return open(path, mode)   # binary: no text kwargs at all\n    return open(path, mode, encoding=encoding, errors=errors, newline=newline)","typeGuard":"def text_kwargs_allowed(mode: str) -> bool:\n    return 'b' not in mode","tryCatchPattern":null,"preventionTips":["Route errors= (and encoding=) through the same text-only gate in shared helpers.","When converting 'r' to 'rb' for speed, strip the text kwargs in the same edit.","Encode a project-level open() wrapper so this rule is applied in exactly one place."],"tags":["io","open","errors","binary-io","valueerror"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}