koala73/worldmonitor · error

Failed to extract push subscription keys.

Error message

Failed to extract push subscription keys.

What it means

UI error in subscribeToPush: the push subscription's payload could not be built because encryption keys were null. This is the known Chrome first-grant bug — the code unsubscribes and retries once; the error means the retry also produced null keys.

Source

Thrown at src/services/push-notifications.ts:167

  let sub = await reg.pushManager.getSubscription();
  if (!sub) {
    sub = await reg.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY) as BufferSource,
    });
  }

  const payload = subscriptionToPayload(sub);
  if (!payload) {
    // Chrome occasionally hands back a subscription with null keys on
    // first-grant. Unsubscribe and retry once.
    await sub.unsubscribe().catch(() => {});
    const retry = await reg.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY) as BufferSource,
    });
    const retryPayload = subscriptionToPayload(retry);
    if (!retryPayload) throw new Error('Failed to extract push subscription keys.');
    await postSubscription(retryPayload, expectedUserId);
    return retryPayload;
  }

  await postSubscription(payload, expectedUserId);
  return payload;
}

/**
 * Shape the error thrown when `/api/notification-channels` rejects a
 * subscription.
 *
 * Every rejection on that route answers with a distinct `error` code —
 * `endpoint host is not a recognised push service`, `pro_required`,
 * `Invalid JSON body`, `MISSING_USER_ID`, … — but the throw used to carry only
 * the HTTP status. That made WORLDMONITOR-XR (3 events / 2 users, Chrome on
 * macOS) permanently undiagnosable: a bare "(400)" cannot distinguish an
 * unrecognised push host from a malformed body from an entitlement denial, and

View on GitHub (pinned to eeab0a219f)

Solutions

  1. Retry subscribing — the Chrome null-keys bug is intermittent
  2. Reload the page and try again if the immediate retry already failed
  3. Report browser/version if it consistently fails — some environments (e.g. certain privacy modes) never hand back keys
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at src/services/push-notifications.ts:167 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of koala73/worldmonitor@eeab0a219f (2026-08-21). Data as JSON: /api/errors/715a4dad36c735a0. Report an issue: GitHub.