Push
Push troubleshooting
Diagnose and fix common WRNexus Web Push problems — service worker scope errors, 410 subscription deactivation, denied permission, missing prompts, and silent notifications.
Common Web Push failure modes and how to resolve them. Turn on SDK logging with
data-debug="true" on the snippet while
debugging — it logs config resolution, worker registration, and subscription
writes to the console.
Service worker scope error
Symptom. The console shows something like “The path of the provided scope
(‘/’) is not under the max scope allowed”, or WRNexusPush.prompt() rejects
because the worker never registers.
Cause. A service worker’s scope is limited to the directory it is served
from. If you serve the worker from a sub-path (e.g. /assets/wrnexus-push-sw.js)
but ask it to control /, the browser refuses.
Fix.
- Best: serve the worker at the site root —
https://your-domain.example/wrnexus-push-sw.js— which gives it the default scope/. - If it must live at a sub-path: send the
Service-Worker-Allowed: /header on the worker response and setdata-sw-scope="/"on the snippet. Both are required. See Service worker setup.
Also confirm the worker is served with Content-Type: text/javascript, over
HTTPS, and at the exact path the snippet’s data-sw points to (default
/wrnexus-push-sw.js).
410 Gone — subscription deactivated
Symptom. A subscriber stops receiving notifications and shows as inactive in
Push → Subscribers, with an unsubscribed event you did not trigger.
Cause. This is expected, healthy behaviour. When the push service reports a
subscription as permanently gone — HTTP 404 or 410 — at send time (the user
cleared site data, the browser rotated and discarded the subscription, or the
push service expired it), WRNexus soft-deactivates that subscription so no
future campaign wastes a send on it. The deactivation flips active = false,
records an unsubscribed event, and updates the campaign’s send row.
Fix. Nothing is broken — this keeps your audience clean. To win the
subscriber back, they simply re-subscribe (WRNexusPush.prompt()) the next time
they visit. To survive routine browser key rotation without losing the
subscriber, fill in the optional WRNEXUS_PUSH_CONFIG re-subscribe block in the
worker — see
Service worker setup.
Permission denied
Symptom. WRNexusPush.prompt() resolves { ok: false, permission: 'denied' }
and no prompt appears.
Cause. The visitor (or a previous prompt) set notification permission to
denied for your origin. Once denied, the browser will not show the prompt
again — Notification.requestPermission() resolves immediately to denied. This
is enforced by the browser, not WRNexus.
Fix.
- You cannot re-prompt programmatically. The user must reset the permission via the site settings (the padlock/site-info icon in the address bar → Notifications → Allow / Reset).
- Check the state first with
WRNexusPush.getPermission()and show your own “notifications are blocked — here’s how to re-enable” hint when it returns'denied', instead of callingprompt()into a no-op.
The prompt never appears (permission is default)
Symptom. Permission is default (not yet decided) but calling prompt()
shows nothing.
Causes & fixes.
- Not a user gesture. Browsers only show the prompt from a real user
interaction. Call
WRNexusPush.prompt()from inside aclickhandler — never on page load, in asetTimeout, or in a promise chain detached from the gesture. - Already subscribed. If the browser already holds a subscription,
prompt()resolves{ ok: true }without re-prompting. Check withWRNexusPush.isSubscribed(). - Unsupported browser / insecure context.
WRNexusPush.isSupported()returnsfalseon browsers without the Push API, or when the page is not served over HTTPS (http://localhostis the only insecure exception).
config() fails — UNKNOWN_SITE or missing VAPID key
Symptom. Debug logs show “push config failed (404)” or “push site is not configured”.
Causes & fixes.
- Wrong site key.
data-site-idmust be the exactpublicKeyfrom Push → Settings. A typo, a trailing space, or using a different site’s key all yieldUNKNOWN_SITE(404). - Inactive site. A soft-deleted or non-
activesite returnsUNKNOWN_SITE. Confirm the site’sstatusisactive. - No active VAPID key.
/push/configonly returns when the site has an active VAPID key (provisioned automatically on site creation). If it is missing, re-create the site.
Notification arrives but is blank or has no icon
Symptom. The notification shows with a default title or no image.
Cause. The worker renders exactly what the campaign payload contains. Missing
title/body/icon on the campaign produces a sparse notification (the worker
falls back to the title "Notification").
Fix. Set title, body, iconUrl, and (optionally) imageUrl on the
campaign. Icons and images must be HTTPS URLs the browser can fetch. The site’s
iconUrl acts as a default when a campaign omits one.
Clicks open but no clicked event is recorded
Symptom. Notifications open the right page but Push → Analytics shows no clicks.
Causes & fixes.
- Stale worker. You are running an old
wrnexus-push-sw.jsthat opensdata.urldirectly instead of the signedclickUrl. Re-copy the latest template from/push/sw.js. - Expired token. Tracking tokens are valid for one year. A click on a
year-old notification hits
/api/push/track/click/{token}and returns410 Gone(the link is shown as expired) — expected for very old notifications. - Tracking is best-effort: an event is never double-counted (counters advance only on the first transition), so re-opening the same notification will not add a second click.
Subscriptions register but campaigns reach nobody
Checklist.
- The subscriber is
active(not deactivated by a 410 — see above). - The campaign’s
siteIdmatches the site the subscribers belong to. - If the campaign has a
topic, the subscriber has not opted out of it in their preferences. - The send is within the site’s frequency cap and outside its quiet hours — a capped or quiet-hours-suppressed send is skipped, not failed.