can1357/oh-my-pi · error · DashboardBundleMissing

frontend bundle missing at {_INDEX_PATH}; run `bun run web:b

Error message

frontend bundle missing at {_INDEX_PATH}; run `bun run web:build`

What it means

`_load_index_template` reads the built frontend `index.html` at `_INDEX_PATH`; when the file does not exist it raises `DashboardBundleMissing` with this message. The library requires a built web bundle (produced by `bun run web:build`) to serve the dashboard, and refuses to render a broken/absent page.

Source

Thrown at python/robomp/src/dashboard.py:101

    """Filesystem path the FastAPI app mounts at `/static`.

    Creates the directory lazily so a fresh checkout (or a runtime container
    that hasn't shipped the bundle yet) can still construct the app —
    `_load_index_template()` raises `DashboardBundleMissing` separately when
    the `index.html` itself is missing. Without this mkdir,
    `StaticFiles(directory=...)` would raise at app construction time and
    block every other route.
    """
    _STATIC_DIR.mkdir(parents=True, exist_ok=True)
    return _STATIC_DIR


@cache
def _load_index_template() -> str:
    try:
        text = _INDEX_PATH.read_text(encoding="utf-8")
    except FileNotFoundError as exc:  # pragma: no cover — repo ships the stub
        raise DashboardBundleMissing(f"frontend bundle missing at {_INDEX_PATH}; run `bun run web:build`") from exc
    if _CONFIG_SENTINEL not in text:
        raise DashboardBundleMissing(
            f"frontend bundle at {_INDEX_PATH} is missing the {_CONFIG_SENTINEL} sentinel; "
            "rebuild with `bun run web:build`"
        )
    return text


def reset_index_cache() -> None:
    """Drop the cached template. Called by tests that swap the static dir."""
    _load_index_template.cache_clear()


def render_index(replay_token: str | None) -> str:
    """Render the dashboard HTML with the server's replay token baked in.

    The token lands inside a `<script type="application/json">` block that the
    page parses at startup and attaches to every privileged fetch. The user

View on GitHub (pinned to 9690622007)

Solutions

  1. Run `bun run web:build` from the repo root to generate the bundle
  2. Verify the build output landed at the path _INDEX_PATH expects (check for index.html)
  3. If deploying, include the built frontend artifact in your deployment package
  4. If a custom path is configured, confirm it matches the actual build output directory
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path
if not _INDEX_PATH.is_file():
    raise RuntimeError("frontend bundle missing — run `bun run web:build` before starting the server")

Try / catch

try:
    html = render_index()
except DashboardBundleMissing:
    return HTTPResponse("Dashboard not built. Run: bun run web:build", status=503)

Prevention

When it happens

Trigger: Calling `render_index` (which invokes `_load_index_template`) when the frontend bundle has never been built, was deleted by a clean, or `_INDEX_PATH` points at a path where the build output was not placed.

Common situations: Running the server from a fresh clone without building the web UI, deploying only the Python package without the build artifact, pointing a custom bundle path at a nonexistent directory.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/6d3f77476888b59d. Report an issue: GitHub.