pallets/flask · error · RuntimeError

No root path can be found for the provided module

Error message

No root path can be found for the provided module {import_name!r}. This can happen because the module came from an import hook that does not provide file name information or because it's a namespace package. In this case the root path needs to be explicitly provided.

What it means

get_root_path(import_name) tries loader.get_filename(import_name); if the loader lacks that method it falls back to __import__ and reads mod.__file__. If __file__ is None (the module is a namespace package or came from an import hook that supplies no file info), it raises RuntimeError telling you to provide the root path explicitly.

Solutions

  1. Pass an explicit root_path to Flask: Flask(__name__, root_path='/abs/path/to/app').
  2. Ensure your package has an __init__.py so it is a regular package with a real __file__.
  3. Pass a concrete module/file path as import_name rather than a namespace package name.

Example fix

# before
app = Flask('my_namespace_pkg')  # namespace package, __file__ is None

# after
app = Flask('my_namespace_pkg', root_path=os.path.dirname(__file__))
# or ensure the package has __init__.py
Defensive patterns

Strategy: validation

Validate before calling

import importlib.util, os

def has_root_path(import_name: str) -> bool:
    spec = importlib.util.find_spec(import_name)
    if spec is None:
        return False
    return bool(spec.origin) and spec.origin != 'namespace'

Type guard

import importlib.util

def is_regular_package(import_name: str) -> bool:
    spec = importlib.util.find_spec(import_name)
    return spec is not None and bool(spec.submodule_search_locations is None)

Try / catch

try:
    app = Flask(import_name)
except RuntimeError:
    app = Flask(import_name, root_path=os.path.dirname(__file__))

Prevention

When it happens

Trigger: Creating a Flask(import_name=...) where import_name resolves to a namespace package (PEP 420, no __init__.py) or a module loaded by a custom importer/meta-path hook that does not set __file__. Because no filesystem path can be derived, Flask cannot compute the root path for static files and templates.

Common situations: Using Flask in a namespace package layout. Dynamically importing the app module via a custom loader. Calling Flask('') or Flask with a name that maps to a synthetic module. Migrating to a src/ layout where the package becomes a namespace package by accident (missing __init__.py).

Related errors


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

Appendix: source

Thrown at src/flask/helpers.py:631

    # Loader does not exist or we're referring to an unloaded main
    # module or a main module without path (interactive sessions), go
    # with the current working directory.
    if loader is None:
        return os.getcwd()

    if hasattr(loader, "get_filename"):
        filepath = loader.get_filename(import_name)  # pyright: ignore
    else:
        # Fall back to imports.
        __import__(import_name)
        mod = sys.modules[import_name]
        filepath = getattr(mod, "__file__", None)

        # If we don't have a file path it might be because it is a
        # namespace package. In this case pick the root path from the
        # first module that is contained in the package.
        if filepath is None:
            raise RuntimeError(
                "No root path can be found for the provided module"
                f" {import_name!r}. This can happen because the module"
                " came from an import hook that does not provide file"
                " name information or because it's a namespace package."
                " In this case the root path needs to be explicitly"
                " provided."
            )

    # filepath is import_name.py for a module, or __init__.py for a package.
    return os.path.dirname(os.path.abspath(filepath))  # type: ignore[no-any-return]


@cache
def _split_blueprint_path(name: str) -> list[str]:
    out: list[str] = [name]

    if "." in name:
        out.extend(_split_blueprint_path(name.rpartition(".")[0]))

View on GitHub (pinned to 3596b1ab61)