{"id":"6f388261c52242d5","repo":"pallets/flask","slug":"resources-can-only-be-opened-for-reading","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/app.py","lineNumber":438,"sourceCode":"        ``app.py`` where the ``Flask`` app is defined, it can be opened\n        with:\n\n        .. code-block:: python\n\n            with app.open_resource(\"schema.sql\") as f:\n                conn.executescript(f.read())\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\n    def open_instance_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 the application's instance folder\n        :attr:`instance_path`. Unlike :meth:`open_resource`, files in the\n        instance folder can be opened for writing.\n\n        :param resource: Path to the resource relative to :attr:`instance_path`.\n        :param mode: Open the file in this mode.\n        :param encoding: Open the file with this encoding when opening in text","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/app.py#L420-L456","documentation":"Raised by `open_resource()` (src/flask/app.py:438) when the `mode` argument is anything other than 'r', 'rt', or 'rb'. Resources under the application's `root_path` are part of the installed package and are considered read-only — the package directory may not be writable (e.g. installed site-packages, zip imports), so Flask forbids write modes by design.","triggerScenarios":"`app.open_resource('schema.sql', mode='w')`, `'a'`, `'wb'`, `'r+'`, or any mode containing write/append/update flags. Same check applies via the Blueprint version of the method.","commonSituations":"Developers trying to persist data (logs, generated files, caches) next to their application code using `open_resource`; porting code that used plain `open()` with write modes; confusion with `open_instance_resource`, which does allow writing because the instance folder is deployment-writable.","solutions":["If you need to write, use `app.open_instance_resource(name, mode='w')` — the instance folder (`app.instance_path`) is meant for writable per-deployment files.","If you only need to read, pass mode 'r', 'rt', or 'rb' (default is 'rb').","For arbitrary writable locations, build the path yourself (e.g. `os.path.join(app.instance_path, name)`) and use plain `open()`."],"exampleFix":"# before\nwith app.open_resource(\"data.json\", mode=\"w\") as f:\n    f.write(payload)\n\n# after\nwith app.open_instance_resource(\"data.json\", mode=\"w\") as f:\n    f.write(payload)","handlingStrategy":"validation","validationCode":"mode = 'rb'\nassert mode in ('r', 'rb', 'rt'), 'open_resource only supports read modes'\nwith app.open_resource('data.json', mode) as f:\n    ...","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only pass 'r', 'rt', or 'rb' to `app.open_resource()` / `open_instance_resource()` when reading package data","Package resources may be read-only (zip/wheel installs); write to `app.instance_path` with plain `open()` instead","Treat resource files as immutable inputs bundled with the app"],"tags":["flask","filesystem","resources","instance-folder"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}