{"record":{"id":"82454d91a8ae231b","repo":"wandb/openui","slug":"asset-not-found-full-path","errorCode":null,"errorMessage":"Asset not found: {full_path}","messagePattern":"Asset not found: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"backend/openui/server.py","lineNumber":581,"sourceCode":"\n# we can serve our annotation iframe from the same domain in development\nif config.ENV != config.Env.PROD:\n    app.mount(\n        \"/openui\",\n        StaticFiles(directory=Path(__file__).parent / \"dist\" / \"annotator\", html=True),\n        name=\"annotator\",\n    )\n\n\n@app.get(\"/{full_path:path}\", include_in_schema=False)\ndef spa(full_path: str):\n    dist_dir = Path(__file__).parent / \"dist\"\n    # TODO: hacky way to only serve index.html on root urls\n    files = [entry.name for entry in dist_dir.iterdir() if entry.is_file()]\n    if full_path in files:\n        return FileResponse(dist_dir / full_path)\n    if \".\" in full_path:\n        raise HTTPException(status_code=404, detail=f\"Asset not found: {full_path}\")\n    return HTMLResponse((dist_dir / \"index.html\").read_bytes())\n\n\nbase_url = \"https://api.wandb.ai\"\ndef check_wandb_auth():\n    global base_url\n    try:\n        from wandb.cli.cli import _get_cling_api\n        api = _get_cling_api()\n        base_url = api.settings(\"base_url\")\n    except:\n        base_url = \"https://api.wandb.ai\"\n    auth = requests.utils.get_netrc_auth(base_url)\n    key = None\n    if auth:\n        key = auth[-1]\n    if os.getenv(\"WANDB_API_KEY\"):\n        key = os.environ[\"WANDB_API_KEY\"]","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/wandb/openui/blob/42d7ab4ab6650433486dfb12eb3783c393a3e475/backend/openui/server.py#L563-L599","documentation":"Raised by OpenUI's SPA catch-all route: when the requested path contains a dot (interpreted as a static asset request), the route checks whether the file exists in the built dist directory; if not, it raises HTTP 404 'Asset not found: {full_path}'. It means the frontend bundle or asset requested was not present in the deployed build output.","triggerScenarios":"Requesting a static path like /assets/index-abc123.js or /favicon.ico that is not a file inside backend/openui/dist — typically after deploying a new build whose hashed filenames changed while the browser cached the old index.html, or serving the app without building the frontend.","commonSituations":"Stale cached index.html referencing old hashed JS/CSS chunks after a redeploy, skipping the frontend build (npm run build) so dist is empty or outdated, CDN caching old asset URLs, or typos in asset paths.","solutions":["Rebuild the frontend (cd frontend && npm run build) and redeploy so dist contains the current hashed assets.","Force clients to fetch fresh index.html (cache-bust or set no-cache on index.html) so they reference the new asset hashes.","Purge CDN/browser caches of old index.html after deployments.","Verify the requested asset path exists under backend/openui/dist; if the path is a real route without an extension, note the 404 only applies to dotted paths."],"exampleFix":"# before (deploy without building -> dist missing assets)\ndocker build -t openui .\n# after\ncd frontend && npm ci && npm run build && cd ..\ndocker build -t openui .","handlingStrategy":"try-catch","validationCode":"// client: detect missing chunk load and hard-reload once\nwindow.addEventListener('error', (e) => {\n  if (e.target?.tagName === 'SCRIPT' && !sessionStorage.getItem('reloaded')) {\n    sessionStorage.setItem('reloaded', '1');\n    location.reload(); // fetch fresh index.html with new hashes\n  }\n}, true);","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(assetUrl);\n  if (res.status === 404) {\n    await purgeAndRebuildIndex(); // refetch / to get new asset hashes\n    return fetch(assetUrl); // retry with updated URL map\n  }\n  return res;\n} catch (err) {\n  showOfflineMessage();\n}","preventionTips":["Always build the frontend before containerizing/deploying","Set index.html to no-cache so clients pick up new hashed assets","Purge CDN caches of index.html on every deploy","Add a smoke test after deploy that GETs the entry JS chunk referenced by index.html"],"tags":["http-404","static-assets","spa","deployment","cache"],"backgroundTag":"missing-static-asset","analyzedSha":"42d7ab4ab6650433486dfb12eb3783c393a3e475","analyzedAt":"2026-09-01T05:00:32.200Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}