reflex-dev/reflex · error · FileNotFoundError

Cannot include stylesheets from outside the assets directory

Error message

Cannot include stylesheets from outside the assets directory: {stylesheet_full_path}

What it means

When compiling the root stylesheet, Reflex refuses any local stylesheet whose absolute path is not inside the app's assets directory. Styles are concatenated into a single root stylesheet, so they must live under .web/assets (or wherever Dirs.APP_ASSETS points) to be found at build time.

Source

Thrown at reflex/compiler/compiler.py:303

def _validate_stylesheet(stylesheet_full_path: Path, assets_app_path: Path) -> None:
    """Validate the stylesheet.

    Args:
        stylesheet_full_path: The stylesheet to validate.
        assets_app_path: The path to the assets directory.

    Raises:
        ValueError: If the stylesheet is not supported.
        FileNotFoundError: If the stylesheet is not found.
    """
    suffix = stylesheet_full_path.suffix[1:] if stylesheet_full_path.suffix else ""
    if suffix not in constants.Reflex.STYLESHEETS_SUPPORTED:
        msg = f"Stylesheet file {stylesheet_full_path} is not supported."
        raise ValueError(msg)
    if not stylesheet_full_path.absolute().is_relative_to(assets_app_path.absolute()):
        msg = f"Cannot include stylesheets from outside the assets directory: {stylesheet_full_path}"
        raise FileNotFoundError(msg)
    if not stylesheet_full_path.name:
        msg = f"Stylesheet file name cannot be empty: {stylesheet_full_path}"
        raise ValueError(msg)
    if (
        len(
            stylesheet_full_path
            .absolute()
            .relative_to(assets_app_path.absolute())
            .parts
        )
        == 1
        and stylesheet_full_path.stem == PageNames.STYLESHEET_ROOT
    ):
        msg = f"Stylesheet file name cannot be '{PageNames.STYLESHEET_ROOT}': {stylesheet_full_path}"
        raise ValueError(msg)


def _compile_root_stylesheet(

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Copy or symlink the stylesheet into your app's assets directory and reference it as "/style.css"
  2. For styles outside the app, load them via a <link> URL (rx.el.link or a hosted URL in add_styles) instead of a local path
  3. Restructure so shared styles ship as a package asset referenced with @pkg: syntax

Example fix

# before
app = rx.App(add_styles=["/home/user/project/shared/style.css"])
# after
app = rx.App(add_styles=["/style.css"])  # file moved into <project>/assets/
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def validate_local_stylesheet(p: str, assets_dir: Path) -> None:
    if p.startswith(("http://", "https://")):
        return
    full = (assets_dir / p.lstrip("/")).resolve()
    if not full.is_relative_to(assets_dir.resolve()):
        raise ValueError(f"stylesheet escapes assets dir: {p}")

Prevention

When it happens

Trigger: Passing an absolute or ../-escaping path in add_styles, e.g. rx.App(add_styles=[str(project_root / "../shared/style.css")]) or "/absolute/path/style.css" outside assets. Any non-URL stylesheet is joined onto assets_app_path and checked with is_relative_to.

Common situations: Monorepo setups where shared styles sit outside the Reflex app directory; generated absolute paths baked into config; moving the assets directory while keeping old absolute references.

Related errors


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/10cd6dcdaad75edb. Report an issue: GitHub.