pallets/flask · error · RuntimeError

'static_folder' must be set to serve static_files.

Error message

'static_folder' must be set to serve static_files.

What it means

Raised by Scaffold.send_static_file() when the object has no static_folder configured. The method serves files out of static_folder via send_from_directory, so without a folder there is nothing to serve. This RuntimeError guards against a null/None path being passed to send_from_directory.

Solutions

  1. Pass a static_folder when constructing the app/blueprint: Flask(__name__, static_folder='static').
  2. If you intentionally disabled static files, remove the code path that calls send_static_file.
  3. Check the value of app.static_folder / blueprint.has_static_folder before calling.

Example fix

// before
app = Flask(__name__, static_folder=None)
app.send_static_file('style.css')  # raises
// after
app = Flask(__name__, static_folder='static')
app.send_static_file('style.css')
Defensive patterns

Strategy: validation

Validate before calling

if not getattr(app, 'has_static_folder', False):
    raise RuntimeError('Cannot serve static files: static_folder is not set')
app.send_static_file('style.css')

Type guard

def can_serve_static(obj) -> bool:
    return bool(getattr(obj, 'has_static_folder', False))

Try / catch

try:
    app.send_static_file(filename)
except RuntimeError as e:
    if 'static_folder' in str(e):
        # serve fallback or 404
        ...
    raise

Prevention

When it happens

Trigger: Calling app.send_static_file('style.css') or blueprint.send_static_file(...) on an instance where static_folder was set to None (the default) or explicitly disabled. Happens if a Blueprint is constructed with static_folder=None and a static route/view still references it.

Common situations: Disabling static files via Flask(__name__, static_folder=None) or Blueprint('bp', __name__, static_folder=None) but still manually mounting or invoking the static view; copying a blueprint config that drops static_folder.

Related errors


AI-assisted analysis of pallets/flask@3596b1ab61 (2026-08-11). Data as JSON: /api/errors/659cfdf18dc82304. Report an issue: GitHub.

Appendix: source

Thrown at src/flask/app.py:406

        if isinstance(value, timedelta):
            return int(value.total_seconds())

        return value  # type: ignore[no-any-return]

    def send_static_file(self, filename: str) -> Response:
        """The view function used to serve files from
        :attr:`static_folder`. A route is automatically registered for
        this view at :attr:`static_url_path` if :attr:`static_folder` is
        set.

        Note this is a duplicate of the same method in the Flask
        class.

        .. versionadded:: 0.5

        """
        if not self.has_static_folder:
            raise RuntimeError("'static_folder' must be set to serve static_files.")

        # send_file only knows to call get_send_file_max_age on the app,
        # call it here so it works for blueprints too.
        max_age = self.get_send_file_max_age(filename)
        return send_from_directory(
            t.cast(str, self.static_folder), filename, max_age=max_age
        )

    def open_resource(
        self, resource: str, mode: str = "rb", encoding: str | None = None
    ) -> t.IO[t.AnyStr]:
        """Open a resource file relative to :attr:`root_path` for reading.

        For example, if the file ``schema.sql`` is next to the file
        ``app.py`` where the ``Flask`` app is defined, it can be opened
        with:

        .. code-block:: python

View on GitHub (pinned to 3596b1ab61)