{"record":{"id":"f8a243a0016a4b15","repo":"koala73/worldmonitor","slug":"account-changed-while-action-try-again","errorCode":null,"errorMessage":"Account changed while ${action}. Try again.","messagePattern":"Account changed while (.+?)\\. Try again\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/billing.ts","lineNumber":93,"sourceCode":"  // Attach the original thrown value as `cause` so Sentry shows it as structured data.\n  // Assigned post-construction because tsconfig target=ES2020 lacks ErrorOptions typing;\n  // Sentry and modern browsers read the property either way.\n  (wrapped as Error & { cause?: unknown }).cause = err;\n  return wrapped;\n}\n\nfunction requireSignedInUserId(action: string): string {\n  const userId = getCurrentClerkUser()?.id;\n  if (!userId) throw new Error(`Sign in to ${action}.`);\n  return userId;\n}\n\nasync function requireCurrentConvexUser(\n  userId: string,\n  action: string,\n): Promise<void> {\n  if (!await waitForConvexAuthForUser(userId)) {\n    throw new Error(`Account changed while ${action}. Try again.`);\n  }\n  assertAccountStillCurrent(userId, action);\n}\n\n/**\n * Initialize the subscription watch for the authenticated user.\n * Idempotent -- calling multiple times is a no-op after the first.\n * Failures are logged but never thrown (dashboard must not break).\n */\nexport async function initSubscriptionWatch(\n  _userId?: string,\n  isCurrent: () => boolean = () => true,\n): Promise<void> {\n  const isExpectedAccount = (): boolean => (\n    isCurrent() && (_userId === undefined || getCurrentClerkUser()?.id === _userId)\n  );\n  if (initialized || !isExpectedAccount()) return;\n","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/koala73/worldmonitor/blob/9361220cc013571781071f0206e4d80fd14b2f7f/src/services/billing.ts#L75-L111","documentation":"Error thrown by requireCurrentConvexUser when the signed-in Clerk user id no longer matches the current Convex user record — the authenticated identity changed mid-session (account switch or re-auth) while a billing action was in flight. Retrying after re-sync resolves it.","triggerScenarios":"Thrown at src/services/billing.ts:81 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the action after the new session settles","Ensure Clerk/Convex identity sync completes after account switches","Avoid switching accounts while a billing dialog is open"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"9361220cc013571781071f0206e4d80fd14b2f7f","analyzedAt":"2026-08-21T16:51:25.751Z","contentChangedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}