{"record":{"id":"33600a1379dd9fb7","repo":"python/cpython","slug":"can-t-have-read-write-append-mode-at-once","errorCode":null,"errorMessage":"can't have read/write/append mode at once","messagePattern":"can't have read/write/append mode at once","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pyio.py","lineNumber":219,"sourceCode":"        raise TypeError(\"invalid buffering: %r\" % buffering)\n    if encoding is not None and not isinstance(encoding, str):\n        raise TypeError(\"invalid encoding: %r\" % encoding)\n    if errors is not None and not isinstance(errors, str):\n        raise TypeError(\"invalid errors: %r\" % errors)\n    modes = set(mode)\n    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 \"\") +","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyio.py#L201-L237","documentation":"Raised by io.open() as a ValueError when the mode string selects more than one of the base operations create(x)/read(r)/write(w)/append(a). Exactly one base operation is required; '+' adds the complementary direction on top of it.","triggerScenarios":"open('f', 'rw') — but note 'rw' usually trips the duplicate-character check (166) first; reachable forms are 'ra', 'rx', 'wa', 'wx', 'ax', and combinations like 'rw+'. Users typically intend 'r+' or 'w+'.","commonSituations":"Programmatic mode composition that ORs independent read and write booleans into concatenated letters; porting C-style 'rw' fopen modes; config schemas that expose separate read:true and write:true flags mapped naively to mode letters.","solutions":["Use 'r+' for read/write without truncation, 'w+' for read/write with truncation, 'a+' for append+read.","Map boolean flag pairs to complete mode strings via a lookup table instead of concatenating letters.","Reject conflicting config flags (read and write both set without an explicit mode) at config-validation time."],"exampleFix":"// before\nmode = ('r' if read else '') + ('w' if write else '')  # 'rw'\nopen(path, mode)\n\n// after\nif read and write:\n    mode = 'r+'    # or 'w+' if truncation desired\nelif write:\n    mode = 'r' if read else 'w'\nelse:\n    mode = 'w' if write else 'r'\n# simpler: choose from {'r','w','a','r+','w+','a+'} directly","handlingStrategy":"validation","validationCode":"BASE_MODES = {'r','w','a','x','r+','w+','a+','x+','rb','wb','ab','xb','r+b','w+b','a+b','x+b'}\n\ndef pick_mode(read: bool, write: bool, binary: bool, truncate: bool) -> str:\n    if read and write:\n        base = 'w+' if truncate else 'r+'\n    elif write:\n        base = 'w'\n    elif read:\n        base = 'r'\n    else:\n        raise ValueError('need read or write')\n    return base + ('b' if binary else '')","typeGuard":"def one_base_op(mode: str) -> bool:\n    return len(set(mode) & {'r','w','a','x'}) == 1","tryCatchPattern":null,"preventionTips":["Map (read, write) flag pairs to complete mode strings via a table instead of letter concatenation.","Remember '+' is the read/write combiner; 'rw'/'wa' are never valid.","Validate config-exposed mode strings against a whitelist."],"tags":["io","open","mode","valueerror"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}