pallets/flask · error · ValueError
Resources can only be opened for reading.
Error message
Resources can only be opened for reading.
What it means
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.
Source
Thrown at src/flask/app.py:438
``app.py`` where the ``Flask`` app is defined, it can be opened
with:
.. code-block:: python
with app.open_resource("schema.sql") as f:
conn.executescript(f.read())
:param resource: Path to the resource relative to :attr:`root_path`.
:param mode: Open the file in this mode. Only reading is supported,
valid values are ``"r"`` (or ``"rt"``) and ``"rb"``.
:param encoding: Open the file with this encoding when opening in text
mode. This is ignored when opening in binary mode.
.. versionchanged:: 3.1
Added the ``encoding`` parameter.
"""
if mode not in {"r", "rt", "rb"}:
raise ValueError("Resources can only be opened for reading.")
path = os.path.join(self.root_path, resource)
if mode == "rb":
return open(path, mode) # pyright: ignore
return open(path, mode, encoding=encoding)
def open_instance_resource(
self, resource: str, mode: str = "rb", encoding: str | None = "utf-8"
) -> t.IO[t.AnyStr]:
"""Open a resource file relative to the application's instance folder
:attr:`instance_path`. Unlike :meth:`open_resource`, files in the
instance folder can be opened for writing.
:param resource: Path to the resource relative to :attr:`instance_path`.
:param mode: Open the file in this mode.
:param encoding: Open the file with this encoding when opening in textView on GitHub ↗ (pinned to 6a2f545bfd)
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()`.
Example fix
# before
with app.open_resource("data.json", mode="w") as f:
f.write(payload)
# after
with app.open_instance_resource("data.json", mode="w") as f:
f.write(payload) Defensive patterns
Strategy: validation
Validate before calling
mode = 'rb'
assert mode in ('r', 'rb', 'rt'), 'open_resource only supports read modes'
with app.open_resource('data.json', mode) as f:
... Prevention
- 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
When it happens
Trigger: `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.
Common situations: 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.
Related errors
- If an instance path is provided it must be absolute. A relat
- Working outside of application context. Attempted to use fu
- Working outside of request context. Attempted to use functi
- The session is unavailable because no secret key was set. S
- The environment variable {variable_name!r} is not set and as
AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31).
Data as JSON: /data/errors/6f388261c52242d5.json.
Report an issue: GitHub ↗.