Skip to content

bug: service worker scope mismatch — SW never activates, cache_version bumps are no-ops #780

@mholzi

Description

@mholzi

Observed

Every page load on /beatify/admin, /beatify/dashboard, and /beatify/player logs:

```
[Admin] SW registration failed: SecurityError: Failed to register a ServiceWorker
for scope ('/beatify/') with script ('/beatify/static/sw.js'):
The path of the provided scope ('/beatify/') is not under the max scope
allowed ('/beatify/static/'). Adjust the scope, move the Service Worker
script, or use the Service-Worker-Allowed HTTP header to allow the scope.
```

Root cause

Browsers limit a service worker's scope to its script's own path or deeper. Beatify serves `sw.js` from `/beatify/static/sw.js` but tries to register it at the broader `/beatify/` scope — blocked by the security check.

Three call sites make this same registration:

Impact

The SW never activates. Everything `sw.js` was built to do (Story 18.5) is dead code in production:

  • No offline/cache-first asset serving
  • `CACHE_VERSION` bumps in `sw.js` do nothing — the cache that version string names doesn't exist
  • `PRECACHE_ASSETS` list is never precached
  • HTML Network-First fallback to cache on disconnect doesn't kick in

This also means the existing rc1/rc2/rc3 `CACHE_VERSION` bumps haven't been doing what the CHANGELOG notes claim — HTML `?v=` cache-busters are the only force-refresh mechanism that actually works today.

Two fix options

Option A (preferred): serve sw.js from /beatify/sw.js

Add a dedicated view that serves `sw.js` at `/beatify/sw.js` (not under `/static/`). Update the three `serviceWorker.register()` call sites to match. The wider scope is then allowed because the script itself lives at the root of that scope.

Option B: add Service-Worker-Allowed header

Serve `/beatify/static/sw.js` with the response header `Service-Worker-Allowed: /beatify/`. Keeps the file location unchanged; only the HTTP response changes. Requires the HA backend view serving static files to set this header for the `sw.js` path specifically.

Spotted during the #772 wizard UX live-test — unrelated, pre-existing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions