{"record":{"id":"6d7a0ee6e3207a6b","repo":"can1357/oh-my-pi","slug":"frontend-bundle-at-index-path-is-missing-the","errorCode":null,"errorMessage":"frontend bundle at {_INDEX_PATH} is missing the {_CONFIG_SENTINEL} sentinel; rebuild with `bun run web:build`","messagePattern":"frontend bundle at (.+?) is missing the (.+?) sentinel; rebuild with `bun run web:build`","errorType":"exception","errorClass":"DashboardBundleMissing","httpStatus":null,"severity":"error","filePath":"python/robomp/src/dashboard.py","lineNumber":103,"sourceCode":"    Creates the directory lazily so a fresh checkout (or a runtime container\n    that hasn't shipped the bundle yet) can still construct the app —\n    `_load_index_template()` raises `DashboardBundleMissing` separately when\n    the `index.html` itself is missing. Without this mkdir,\n    `StaticFiles(directory=...)` would raise at app construction time and\n    block every other route.\n    \"\"\"\n    _STATIC_DIR.mkdir(parents=True, exist_ok=True)\n    return _STATIC_DIR\n\n\n@cache\ndef _load_index_template() -> str:\n    try:\n        text = _INDEX_PATH.read_text(encoding=\"utf-8\")\n    except FileNotFoundError as exc:  # pragma: no cover — repo ships the stub\n        raise DashboardBundleMissing(f\"frontend bundle missing at {_INDEX_PATH}; run `bun run web:build`\") from exc\n    if _CONFIG_SENTINEL not in text:\n        raise DashboardBundleMissing(\n            f\"frontend bundle at {_INDEX_PATH} is missing the {_CONFIG_SENTINEL} sentinel; \"\n            \"rebuild with `bun run web:build`\"\n        )\n    return text\n\n\ndef reset_index_cache() -> None:\n    \"\"\"Drop the cached template. Called by tests that swap the static dir.\"\"\"\n    _load_index_template.cache_clear()\n\n\ndef render_index(replay_token: str | None) -> str:\n    \"\"\"Render the dashboard HTML with the server's replay token baked in.\n\n    The token lands inside a `<script type=\"application/json\">` block that the\n    page parses at startup and attaches to every privileged fetch. The user\n    never sees or types it; the only credential to manage is the env var on\n    the server itself.","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/dashboard.py#L85-L121","documentation":"`_load_index_template` found the frontend `index.html` but it does not contain the expected `_CONFIG_SENTINEL` marker string, so it raises `DashboardBundleMissing`. The sentinel proves the bundle was produced by the current build pipeline (which injects runtime config placeholders); an old, stale, or hand-made index.html without it cannot be configured correctly, so the library refuses to serve it.","triggerScenarios":"Calling `render_index` after the index.html at `_INDEX_PATH` was built by an older build script, copied from a different project, hand-edited so the sentinel was removed, or partially overwritten.","commonSituations":"Stale build artifacts from a previous version surviving a cache, mixing a rebuilt Python package with an old web build, CI restoring an outdated cached `dist/` directory.","solutions":["Run `bun run web:build` again from the repo root to regenerate index.html with the sentinel","Clear any cached/copied build output (dist/, build cache) and rebuild from a clean tree","Do not hand-edit the generated index.html — change the build pipeline that emits the sentinel instead","Pin deploy pipelines to rebuild the web bundle rather than reusing artifact caches"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"text = _INDEX_PATH.read_text(encoding=\"utf-8\") if _INDEX_PATH.is_file() else \"\"\nbundle_ok = _CONFIG_SENTINEL in text","typeGuard":null,"tryCatchPattern":"try:\n    html = render_index()\nexcept DashboardBundleMissing as exc:\n    log.warning(\"stale frontend bundle: %s — rebuilding\", exc)\n    subprocess.run([\"bun\", \"run\", \"web:build\"], check=True)\n    html = render_index()","preventionTips":["Always rebuild the bundle after upgrading the package or web sources","Never hand-edit generated index.html","Invalidate CI caches of dist/ on build-script changes","Verify the sentinel (a quick string check) in deployment smoke tests"],"tags":["build","frontend","stale-cache","dashboard"],"backgroundTag":"missing-build-artifact","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}