{"record":{"id":"a6b830c01c2ec157","repo":"juicedata/juicefs","slug":"invalid-mode-mode","errorCode":null,"errorMessage":"invalid mode: {mode}","messagePattern":"invalid mode: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdk/python/juicefs/juicefs/juicefs.py","lineNumber":205,"sourceCode":"\n    def stat(self, path):\n        \"\"\"Get the status of a file or a directory.\"\"\"\n        fi = FileInfo()\n        self.lib.jfs_stat(c_int64(_tid()), c_int64(self.h), _bin(path), byref(fi))\n        return os.stat_result((fi.mode, fi.inode, 0, fi.nlink, fi.uid, fi.gid, fi.length, fi.atime, fi.mtime, fi.ctime))\n\n    def exists(self, path):\n        \"\"\"Check if a file exists.\"\"\"\n        try:\n            self.stat(path)\n            return True\n        except OSError as e:\n            return False\n\n    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\")","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/sdk/python/juicefs/juicefs/juicefs.py#L187-L223","documentation":"JuiceFileSystem.open() validates the mode string like builtin open(): it rejects modes containing duplicate characters (len(mode) != len(set(mode))) and unknown characters. This specific raise covers both duplicate characters and any character not in 'rwxa+tb' encountered in the parse loop. It's a fail-fast ValueError before any file operation.","triggerScenarios":"open(path, 'rr'), open(path, 'w+w'), or open(path, 'q') — any mode with a repeated character or a character outside rwxa+tb.","commonSituations":"Programmatically building a mode string and duplicating flags; typos ('re' containing 'e'); porting code that uses C-style modes like 'rb+' is fine, but 'z' or 'O_RDWR' constants leaked into the string are not.","solutions":["Use a mode with unique characters drawn only from 'rwxa', plus optional '+' and 'tb'.","Include exactly one of r/w/x/a — see also the cnt != 1 check.","Match Python's builtin open() mode grammar: e.g. 'r', 'rb', 'w', 'w+', 'a'."],"exampleFix":"# before\nf = jfs.open(path, 'rw')  # duplicates? 'rw' ok, but 'rr' or 'rww' fails\n# after\nf = jfs.open(path, 'r+')  # read+write with a single 'r'/'w' base","handlingStrategy":"validation","validationCode":"def validate_mode(mode):\n    if len(mode) != len(set(mode)) or any(c not in 'rwxa+tb' for c in mode):\n        raise ValueError(f'invalid mode: {mode}')\n    return mode","typeGuard":"def is_valid_mode(mode) -> bool:\n    return isinstance(mode, str) and len(mode) == len(set(mode)) and all(c in 'rwxa+tb' for c in mode)","tryCatchPattern":"try:\n    f = jfs.open(path, mode)\nexcept ValueError as e:\n    if 'invalid mode' in str(e):\n        mode = sanitize_mode(mode)\n        f = jfs.open(path, mode)\n    else:\n        raise","preventionTips":["Reuse the same mode strings as builtin open(): r, rb, w, wb, a, r+, w+.","Never build mode strings by concatenation without deduplication.","Sanitize user/config-supplied modes before passing them to open()."],"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-14T00:17:10.932Z"}