{"id":"e2f2ac59eabf1839","repo":"pallets/flask","slug":"resources-can-only-be-opened-for-reading-e2f2ac","errorCode":null,"errorMessage":"Resources can only be opened for reading.","messagePattern":"Resources can only be opened for reading\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/flask/blueprints.py","lineNumber":121,"sourceCode":"\n    def open_resource(\n        self, resource: str, mode: str = \"rb\", encoding: str | None = \"utf-8\"\n    ) -> t.IO[t.AnyStr]:\n        \"\"\"Open a resource file relative to :attr:`root_path` for reading. The\n        blueprint-relative equivalent of the app's :meth:`~.Flask.open_resource`\n        method.\n\n        :param resource: Path to the resource relative to :attr:`root_path`.\n        :param mode: Open the file in this mode. Only reading is supported,\n            valid values are ``\"r\"`` (or ``\"rt\"``) and ``\"rb\"``.\n        :param encoding: Open the file with this encoding when opening in text\n            mode. This is ignored when opening in binary mode.\n\n        .. versionchanged:: 3.1\n            Added the ``encoding`` parameter.\n        \"\"\"\n        if mode not in {\"r\", \"rt\", \"rb\"}:\n            raise ValueError(\"Resources can only be opened for reading.\")\n\n        path = os.path.join(self.root_path, resource)\n\n        if mode == \"rb\":\n            return open(path, mode)  # pyright: ignore\n\n        return open(path, mode, encoding=encoding)\n","sourceCodeStart":103,"sourceCodeEnd":129,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/blueprints.py#L103-L129","documentation":"Blueprint.open_resource (like Flask.open_resource) only supports read modes — it validates mode against {'r', 'rt', 'rb'} and raises ValueError otherwise. Resources are meant to be read-only package data relative to root_path; writing to installed package directories is unsupported and often impossible (zip imports, read-only installs).","triggerScenarios":"Calling bp.open_resource('data.txt', mode='w'), 'a', 'r+', 'wb', or any mode string outside 'r'/'rt'/'rb'.","commonSituations":"Trying to persist user data or caches next to package code; porting open() calls to open_resource without adjusting the mode; templating tools writing generated files through the resource API.","solutions":["Use a read mode: bp.open_resource('data.txt') or mode='rb' for binary.","For writable data, open a path under app.instance_path (or another writable directory) with the builtin open() instead.","If you only need the file contents, consider importlib.resources for package data."],"exampleFix":"# before\nwith bp.open_resource('cache.json', mode='w') as f: ...\n# after\nimport os\nwith open(os.path.join(app.instance_path, 'cache.json'), 'w') as f: ...","handlingStrategy":"validation","validationCode":"mode = 'rb'  # only read modes allowed\nassert 'w' not in mode and 'a' not in mode and '+' not in mode, \"open_resource only supports read modes\"\nwith bp.open_resource('data/schema.sql', mode) as f:\n    data = f.read()","typeGuard":"def is_read_mode(mode: str) -> bool:\n    return mode in ('r', 'rt', 'rb')","tryCatchPattern":null,"preventionTips":["Treat open_resource as read-only; resources are package data, not writable storage","For writable files use app.instance_path with plain open()","Never pass user-supplied mode strings to open_resource"],"tags":["flask","blueprint","file-io"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}