{"record":{"id":"ff4a03187bd6f02c","repo":"juicedata/juicefs","slug":"must-have-exactly-one-of-create-read-write-append","errorCode":null,"errorMessage":"must have exactly one of create/read/write/append mode","messagePattern":"must have exactly one of create/read/write/append mode","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdk/python/juicefs/juicefs/juicefs.py","lineNumber":220,"sourceCode":"    def open(self, path, mode='r', buffering=-1, encoding=None, errors=None):\n        \"\"\"Open a file, returns a filelike object.\"\"\"\n        if len(mode) != len(set(mode)):\n            raise ValueError(f'invalid mode: {mode}')\n        flag = 0\n        cnt = 0\n        for c in mode:\n            if c in 'rwxa':\n                cnt += 1\n                if c == 'r':\n                    flag |= MODE_READ\n                else:\n                    flag |= MODE_WRITE\n            elif c == '+':\n                flag |= MODE_READ | MODE_WRITE\n            elif c not in 'tb':\n                raise ValueError(f'invalid mode: {mode}')\n        if cnt != 1:\n            raise ValueError('must have exactly one of create/read/write/append mode')\n        if 'b' in mode:\n            if 't' in mode:\n                raise ValueError(\"can't have text and binary mode at once\")\n            if encoding:\n                raise ValueError(\"binary mode doesn't take an encoding argument\")\n            if errors:\n                raise ValueError(\"binary mode doesn't take an errors argument\")\n        else:\n            if not encoding:\n                encoding = locale.getpreferredencoding(False).lower()\n            if not errors:\n                errors = 'strict'\n            codecs.lookup(encoding)\n\n        size = 0\n        if 'x' in mode:\n            fd = self.lib.jfs_create(c_int64(_tid()), c_int64(self.h), _bin(path), c_uint16(0o666), c_uint16(self.umask))\n        else:","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/sdk/python/juicefs/juicefs/juicefs.py#L202-L238","documentation":"After scanning the mode characters, open() requires exactly one base mode: r, w, x or a. cnt != 1 (zero base modes like '+' or 'tb' alone, or multiple like 'rwa') raises this ValueError. Mirrors CPython's builtin open() error message.","triggerScenarios":"open(path, '+'), open(path, 'b'), open(path, 't'), open(path, 'rwa'), open(path, '') — zero or 2+ base-mode characters.","commonSituations":"Constructing the mode dynamically and ending up with only '+' or 'b'; concatenating 'a' onto 'rw' making 'rwa'; empty mode string from a config value defaulting to ''.","solutions":["Set exactly one of 'r', 'w', 'x' or 'a' in the mode string.","For read+write use 'r+' or 'w+' rather than 'rw'.","Validate config-supplied modes against ^(r|w|x|a)[+]?[tb]?$ before calling open."],"exampleFix":"# before\nf = jfs.open(path, 'rw')   # two base modes\n# after\nf = jfs.open(path, 'r+')   # exactly one base mode","handlingStrategy":"validation","validationCode":"import re\nif not re.fullmatch(r'(r|w|x|a)\\+?[tb]?', mode):\n    raise ValueError(f'mode must have exactly one of r/w/x/a: {mode}')","typeGuard":"def has_exactly_one_base_mode(mode) -> bool:\n    return isinstance(mode, str) and sum(c in 'rwxa' for c in mode) == 1","tryCatchPattern":"try:\n    f = jfs.open(path, mode)\nexcept ValueError as e:\n    if 'exactly one of create/read/write/append' in str(e):\n        f = jfs.open(path, mode + 'r' if sum(c in 'rwxa' for c in mode) == 0 else 'r+')\n    else:\n        raise","preventionTips":["Use 'r+'/'w+' instead of 'rw' for combined read-write.","Never pass '' or modifier-only modes like '+' or 'b'.","Validate config/default modes against a strict regex at startup."],"tags":["python","file-open","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}