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 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.
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.
Example fix
// before
with app.open_resource('seed.json', mode='w') as f: # raises
f.write('{}')
// after
import os
path = os.path.join(app.instance_path, 'seed.json')
with open(path, 'w', encoding='utf-8') as f:
f.write('{}') Defensive patterns
Strategy: validation
Validate before calling
READ_MODES = {'r', 'rt', 'rb'}
if mode not in READ_MODES:
raise ValueError(f'open_resource requires a read mode, got {mode!r}')
app.open_resource('data.json', mode=mode) Type guard
def is_read_mode(mode: str) -> bool:
return mode in {'r', 'rt', 'rb'} Try / catch
try:
with app.open_resource(path, mode=mode) as f:
...
except ValueError as e:
if 'only be opened for reading' in str(e):
# switch to writable path
...
raise Prevention
- 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.
When it happens
Trigger: Calling app.open_resource('data.json', mode='w') or blueprint.open_resource('config.toml', mode='a') with any mode containing 'w', 'a', '+', or 'x'.
Common situations: Developer assumes open_resource mirrors open() semantics and tries to write to a bundled resource; porting code that used open() on resource paths.
Related errors
AI-assisted analysis of pallets/flask@3596b1ab61 (2026-08-11).
Data as JSON: /api/errors/6f388261c52242d5.
Report an issue: GitHub.
Appendix: source
Thrown at src/flask/app.py:439
``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 3596b1ab61)