koala73/worldmonitor · warning

Not authenticated

Error message

Not authenticated

What it means

Thrown by authFetch() in src/services/push-notifications.ts when getClerkToken() resolves to null while trying to attach a Bearer header to a push-registration request. Clerk yields no token when there is no active session: the user is signed out, the session expired, or Clerk has not finished initializing. The fetch is never issued.

Source

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

    auth,
    userAgent: typeof navigator !== 'undefined' ? navigator.userAgent.slice(0, 200) : '',
  };
}

function assertExpectedAccount(expectedUserId?: string): void {
  if (expectedUserId && getCurrentClerkUser()?.id !== expectedUserId) {
    throw new Error('Authenticated account changed during push setup');
  }
}

async function authFetch(
  path: string,
  init: RequestInit,
  expectedUserId?: string,
): Promise<Response> {
  assertExpectedAccount(expectedUserId);
  const token = await getClerkToken();
  if (!token) throw new Error('Not authenticated');
  assertExpectedAccount(expectedUserId);
  return fetch(path, {
    ...init,
    headers: {
      'Content-Type': 'application/json',
      ...(init.headers ?? {}),
      Authorization: `Bearer ${token}`,
    },
  });
}

/**
 * Ask permission (if needed), subscribe via pushManager, and register
 * the endpoint with the server. Resolves with the payload the server
 * accepted, or throws on cancel / denial / network failure.
 */
export async function subscribeToPush(expectedUserId?: string): Promise<SubscriptionPayload> {
  assertExpectedAccount(expectedUserId);

View on GitHub (pinned to eeab0a219f)

Solutions

  1. Re-authenticate (open Clerk sign-in) and retry the push setup.
  2. Gate push UI behind a signed-in check (getCurrentClerkUser()) so unauthenticated users never reach the fetch.
  3. Ensure Clerk is fully loaded before mounting push controls (await Clerk's loaded state).
  4. Treat this message as 'sign in required' UX copy, not a generic failure.

Example fix

// before
await subscribeToPush(userId);

// after
import { getCurrentClerkUser } from '@/services/clerk';
if (!getCurrentClerkUser()) {
  await clerkOpenSignIn();
  return;
}
await subscribeToPush(userId);
Defensive patterns

Strategy: validation

Validate before calling

import { getCurrentClerkUser } from '@/services/clerk';

if (!getCurrentClerkUser()) {
  await openClerkSignIn();
  return;
}
await subscribeToPush(expectedUserId);

Type guard

function isNotAuthenticated(err: unknown): boolean {
  return err instanceof Error && err.message === 'Not authenticated';
}

Try / catch

try {
  await subscribeToPush(expectedUserId);
} catch (err) {
  if (isNotAuthenticated(err)) {
    await openClerkSignIn(); // session needed before push registration can continue
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling subscribeToPush/unsubscribeToPush (or any push endpoint call via authFetch) while signed out; after session expiry in a long-open tab; during the brief window before Clerk hydrates after page load; when Clerk JS failed to load so no session exists.

Common situations: Users leaving the dashboard open past the session TTL then enabling notifications; interacting with a push toggle rendered before Clerk finished loading; browser extensions or networks blocking Clerk's script.

Understand the failure class

Related errors


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