koala73/worldmonitor · error

Failed to register push subscription

Error message

Failed to register push subscription (${res.status})${code ? `: ${code}` : ''}.

What it means

UI error in postSubscription (push-notifications): the server rejected the registration POST to /api/notification-channels with a non-OK status. The status code and any JSON 'error' field (up to 120 chars) are included in the message to identify the server-side reason.

Solutions

  1. Address the server 'code' if present (e.g. invalid payload, duplicate subscription)
  2. Retry on transient 5xx statuses
  3. Check authentication if the status is 401/403 — the session may have expired
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at src/services/push-notifications.ts:215 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/2cda0e1d37d43089. Report an issue: GitHub.

Appendix: source

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

    const parsed: unknown = JSON.parse(await res.text());
    const error = (parsed as { error?: unknown } | null)?.error;
    if (typeof error === 'string' && error) code = error.slice(0, 120);
  } catch {
    // Non-JSON body (or an unreadable stream) — the status is all we have.
  }
  return `Failed to register push subscription (${res.status})${code ? `: ${code}` : ''}.`;
}

async function postSubscription(
  payload: SubscriptionPayload,
  expectedUserId?: string,
): Promise<void> {
  const res = await authFetch('/api/notification-channels', {
    method: 'POST',
    body: JSON.stringify({ action: 'set-web-push', ...payload }),
  }, expectedUserId);
  if (!res.ok) {
    throw new Error(await describePushRegistrationFailure(res));
  }
}

/** Reverse of subscribeToPush: unregisters with the server and the browser. */
export async function unsubscribeFromPush(): Promise<void> {
  const reg = await getRegistration();
  if (reg) {
    const sub = await reg.pushManager.getSubscription().catch(() => null);
    if (sub) {
      // Best-effort browser-side unsubscribe. If the network delete
      // fails we still want the browser subscription removed so the
      // user isn't left with a phantom channel.
      await sub.unsubscribe().catch(() => {});
    }
  }
  try {
    await authFetch('/api/notification-channels', {
      method: 'POST',

View on GitHub (pinned to eeab0a219f)