{"record":{"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":439,"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":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/pallets/flask/blob/3596b1ab61cea85edb8970e83ff61daa073facf8/src/flask/app.py#L421-L457","documentation":"Raised by Scaffold.open_resource() when the requested file mode is not one of the read-only modes {\"r\", \"rt\", \"rb\"}. Resources are read-only by contract; the method rejects write/append modes to prevent accidental mutation of packaged files.","triggerScenarios":"Calling app.open_resource('data.json', mode='w') or blueprint.open_resource('config.toml', mode='a') with any mode containing 'w', 'a', '+', or 'x'.","commonSituations":"Developer assumes open_resource mirrors open() semantics and tries to write to a bundled resource; porting code that used open() on resource paths.","solutions":["Use a read mode: app.open_resource('data.json', mode='r', encoding='utf-8').","For writing, use open_instance_resource() or open() against an absolute writable path outside the package.","If mutation is required, write to the instance folder via app.instance_path instead."],"exampleFix":"// before\nwith app.open_resource('seed.json', mode='w') as f:  # raises\n    f.write('{}')\n// after\nimport os\npath = os.path.join(app.instance_path, 'seed.json')\nwith open(path, 'w', encoding='utf-8') as f:\n    f.write('{}')","handlingStrategy":"validation","validationCode":"READ_MODES = {'r', 'rt', 'rb'}\nif mode not in READ_MODES:\n    raise ValueError(f'open_resource requires a read mode, got {mode!r}')\napp.open_resource('data.json', mode=mode)","typeGuard":"def is_read_mode(mode: str) -> bool:\n    return mode in {'r', 'rt', 'rb'}","tryCatchPattern":"try:\n    with app.open_resource(path, mode=mode) as f:\n        ...\nexcept ValueError as e:\n    if 'only be opened for reading' in str(e):\n        # switch to writable path\n        ...\n    raise","preventionTips":["Treat open_resource as strictly read-only at the API boundary.","Reserve open_instance_resource or plain open() for writes.","Validate mode against {r, rt, rb} before calling."],"tags":["resources","io","value-error"],"backgroundTag":null,"analyzedSha":"3596b1ab61cea85edb8970e83ff61daa073facf8","analyzedAt":"2026-08-11T20:11:52.622Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}