koala73/worldmonitor · error · Error

Sign in to .

Error message

Sign in to ${action}.

What it means

Error thrown by requireSignedInUserId in the browser billing service when no current Clerk user id is available — the visitor is not signed in. It is a generic auth precondition guard: any billing action named by the interpolated verb (open portal, invite seats, claim activation, …) requires an authenticated session first.

Solutions

  1. Prompt the user to sign in via Clerk before retrying the billing action
  2. Ensure the Clerk auth state is fully loaded before invoking billing service functions
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/services/billing.ts:72 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-08-21). Data as JSON: /api/errors/431554be5ca2c8f1. Report an issue: GitHub.

Appendix: source

Thrown at src/services/billing.ts:77

function normalizeCaughtError(action: string, err: unknown): Error {
  if (err instanceof Error) return err;
  // Chrome iOS / WKWebView: DOMException is not always `instanceof Error`, so
  // a SecurityError from window.open / location assignment fell through to the
  // synthetic "threw non-Error: …" branch below and titled its Sentry issue
  // after the wrapper rather than the fault (WORLDMONITOR-11D). Keep the
  // `[billing] <action>:` prefix every other error from this module carries —
  // without it the same fault produces two differently-shaped titles depending
  // on which branch caught it, and neither says where it happened.
  if (typeof DOMException !== 'undefined' && err instanceof DOMException) {
    return new Error(`[billing] ${action}: ${err.name}: ${err.message}`, { cause: err });
  }
  const rendered = err === undefined ? 'undefined' : String(err);
  return new Error(`[billing] ${action} threw non-Error: ${rendered}`, { cause: err });
}

function requireSignedInUserId(action: string): string {
  const userId = getCurrentClerkUser()?.id;
  if (!userId) throw new Error(`Sign in to ${action}.`);
  return userId;
}

async function requireCurrentConvexUser(
  userId: string,
  action: string,
): Promise<void> {
  if (!await waitForConvexAuthForUser(userId)) {
    throw new Error(`Account changed while ${action}. Try again.`);
  }
  assertAccountStillCurrent(userId, action);
}

/**
 * Initialize the subscription watch for the authenticated user.
 * Idempotent -- calling multiple times is a no-op after the first.
 * Failures are logged but never thrown (dashboard must not break).
 */

View on GitHub (pinned to 7d06c8633d)