pallets/flask · error · ValueError
Resources can only be opened for reading.
Error message
Resources can only be opened for reading.
What it means
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).
Source
Thrown at src/flask/blueprints.py:121
def open_resource(
self, resource: str, mode: str = "rb", encoding: str | None = "utf-8"
) -> t.IO[t.AnyStr]:
"""Open a resource file relative to :attr:`root_path` for reading. The
blueprint-relative equivalent of the app's :meth:`~.Flask.open_resource`
method.
: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)
View on GitHub ↗ (pinned to 6a2f545bfd)
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.
Example fix
# before
with bp.open_resource('cache.json', mode='w') as f: ...
# after
import os
with open(os.path.join(app.instance_path, 'cache.json'), 'w') as f: ... Defensive patterns
Strategy: validation
Validate before calling
mode = 'rb' # only read modes allowed
assert 'w' not in mode and 'a' not in mode and '+' not in mode, "open_resource only supports read modes"
with bp.open_resource('data/schema.sql', mode) as f:
data = f.read() Type guard
def is_read_mode(mode: str) -> bool:
return mode in ('r', 'rt', 'rb') Prevention
- 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
When it happens
Trigger: Calling bp.open_resource('data.txt', mode='w'), 'a', 'r+', 'wb', or any mode string outside 'r'/'rt'/'rb'.
Common situations: 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.
Related errors
- 'static_folder' must be set to serve static_files.
- 'view_func' name may not contain a dot '.' character.
- 'static_folder' must be set to serve static_files.
- Working outside of application context. Attempted to use fu
- Working outside of request context. Attempted to use functi
AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31).
Data as JSON: /data/errors/e2f2ac59eabf1839.json.
Report an issue: GitHub ↗.