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 text

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. 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.
  2. If you only need to read, pass mode 'r', 'rt', or 'rb' (default is 'rb').
  3. 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

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


AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31). Data as JSON: /data/errors/6f388261c52242d5.json. Report an issue: GitHub ↗.