{"record":{"id":"f302670b9a48d596","repo":"koala73/worldmonitor","slug":"account-changed-while-revoking-the-api-key-try-ag","errorCode":null,"errorMessage":"Account changed while revoking the API key. Try again.","messagePattern":"Account changed while revoking the API key\\. Try again\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/api-keys.ts","lineNumber":110,"sourceCode":"    throw new Error('Authentication unavailable while loading API keys. Try again.');\n  }\n\n  return settleAccountOperation(\n    userId,\n    'loading API keys',\n    () => client.query((api as any).apiKeys.listApiKeys, {}),\n  );\n}\n\n/** Revoke an API key by its Convex document ID. */\nexport async function revokeApiKey(keyId: string): Promise<void> {\n  const userId = getCurrentClerkUser()?.id;\n  if (!userId) throw new Error('Sign in to revoke API keys.');\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 revoking the API key. Try again.');\n  }\n\n  const result = await settleAccountOperation(\n    userId,\n    'revoking the API key',\n    () => client.mutation((api as any).apiKeys.revokeApiKey, { keyId }),\n  );\n  assertAccountStillCurrent(userId, 'revoking the API key');\n\n  // Await cache bust so the gateway stops accepting the revoked key immediately.\n  // If this fails, the 60s cache TTL limits the staleness window.\n  if (result?.keyHash) {\n    const token = await settleAccountOperation(\n      userId,\n      'invalidating the API key cache',\n      getClerkToken,\n    );\n    if (token) {","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/koala73/worldmonitor/blob/eeab0a219fce0f02a00603b532dbae9041b934ac/src/services/api-keys.ts#L92-L128","documentation":"UI service error in revokeApiKey (via assertAccountStillCurrent): the authenticated user changed between starting and completing the revocation, so the operation is aborted rather than revoking a key under the wrong account.","triggerScenarios":"Thrown at src/services/api-keys.ts:110 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry revocation after the account state settles","Do not switch accounts while a revocation is in flight"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"eeab0a219fce0f02a00603b532dbae9041b934ac","analyzedAt":"2026-08-21T16:51:25.751Z","contentChangedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}