{"record":{"id":"0fa6fbe0fcc892d9","repo":"koala73/worldmonitor","slug":"account-changed-while-creating-the-embed-key-try-again","errorCode":null,"errorMessage":"Account changed while creating the embed key. Try again.","messagePattern":"Account changed while creating the embed key\\. Try again\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/embed-keys.ts","lineNumber":92,"sourceCode":"  return plaintext.slice(0, 9);\n}\n\n/**\n * Create a new embed key for the current user.\n * Returns the full plaintext key (shown once) and metadata.\n */\nexport async function createEmbedKey(name: string): Promise<CreateEmbedKeyResult> {\n  const userId = getCurrentClerkUser()?.id;\n  if (!userId) throw new Error('Sign in to create an embed key.');\n\n  const plaintext = generateEmbedKey();\n  const keyPrefix = embedKeyPrefix(plaintext);\n  const keyHash = await sha256Hex(plaintext);\n\n  const [client, api] = await Promise.all([getConvexClient(), getConvexApi()]);\n  if (!client || !api) throw new Error('Convex unavailable');\n  if (!await waitForConvexAuthForUser(userId)) {\n    throw new Error('Account changed while creating the embed key. Try again.');\n  }\n\n  const result = await settleAccountOperation(\n    userId,\n    'creating the embed key',\n    () => client.mutation(\n      (api as any).embedKeys.createEmbedKey,\n      { name: name.trim(), keyPrefix, keyHash },\n    ),\n  );\n  assertAccountStillCurrent(userId, 'creating the embed key');\n\n  return { id: result.id, name: result.name, keyPrefix: result.keyPrefix, key: plaintext };\n}\n\n/** List all embed keys for the current user. */\nexport async function listEmbedKeys(): Promise<EmbedKeyInfo[]> {\n  const userId = getCurrentClerkUser()?.id;","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/src/services/embed-keys.ts#L74-L110","documentation":"After confirming the Convex client exists, createEmbedKey waits for Clerk auth to become available for the captured userId via waitForConvexAuthForUser. If auth never resolves for that user — typically because the signed-in account changed mid-operation — the key is not created and this error tells the user to retry.","triggerScenarios":"User signs out or switches Clerk accounts between the createEmbedKey call capturing userId and the Convex mutation needing an authenticated token for that userId; waitForConvexAuthForUser returns false.","commonSituations":"User clicking 'create key' in one tab while signing out in another; account switcher used during the operation; slow Clerk token refresh colliding with a sign-out; session expiry racing with the mutation.","solutions":["Simply retry the operation while staying signed in to the same account.","Avoid switching or signing out of the Clerk account until the key creation completes.","Re-check the current user id before the mutation and abort early if it changed.","If it reproduces without account changes, inspect Clerk token loading/refresh for the user."],"exampleFix":"// before\nif (!await waitForConvexAuthForUser(userId)) {\n  throw new Error('Account changed while creating the embed key. Try again.');\n}\n// after\nconst latestUserId = getCurrentClerkUser()?.id;\nif (latestUserId !== userId) throw new Error('Account changed while creating the embed key. Try again.');\nif (!await waitForConvexAuthForUser(userId)) throw new Error('Sign-in not ready; try again.');","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await createEmbedKey(name);\n} catch (e) {\n  if (e.message.startsWith('Account changed')) setStatus('Session changed — please try again.');\n  else throw e;\n}","preventionTips":["Don't switch or sign out of accounts mid-operation.","Re-read the current user id immediately before the mutation and compare.","Keep sessions refreshed so token availability doesn't lag behind the operation."],"tags":["race-condition","authentication","convex","clerk"],"backgroundTag":"invalid-state-transition","analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-09-15T16:44:39.439Z","contentChangedAt":"2026-09-15T16:44:39.439Z","schemaVersion":2},"datasetVersion":"2026-09-15T18:17:12.389Z"}