koala73/worldmonitor · error

Account changed while revoking the embed key. Try again.

Error message

Account changed while revoking the embed key. Try again.

What it means

After obtaining the Convex client, revokeEmbedKey awaits waitForConvexAuthForUser(userId); if auth does not confirm for that exact user within the window it throws this error. It means the authenticated identity changed (or never settled) between reading the user and issuing the mutation — a guard against revoking keys under the wrong account.

Solutions

  1. Simply retry after the account situation settles — the message explicitly says 'Try again'
  2. Re-read getCurrentClerkUser() after the failure; if the user id changed, re-run the action in the new session only if that user owns the key
  3. Avoid switching accounts while a destructive action is in flight; disable action buttons during pending auth transitions

Example fix

// before
await revokeEmbedKey(keyId);
// after
try {
  await revokeEmbedKey(keyId);
} catch (e) {
  if (/Account changed/.test(e.message)) {
    showToast('Your account changed. Please retry the revocation.');
  } else throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

const uid = getCurrentClerkUser()?.id; if (!uid) return;

Try / catch

try { await revokeEmbedKey(keyId); } catch (e) { if (/Account changed/.test(e.message)) { promptRetryAfterAccountSettles(); } else throw e; }

Prevention

When it happens

Trigger: Calling revokeEmbedKey() and the Clerk account switches (sign-out, sign-in as another user, session token rotation failing) while waiting for Convex auth to settle for the original userId.

Common situations: User A clicks revoke, then the tab completes a sign-in as user B; session expiry mid-action; multi-tab account switching; slow Convex auth causing the wait to time out right as the user changes accounts.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15). Data as JSON: /api/errors/59c1410c702f6645. Report an issue: GitHub.

Appendix: source

Thrown at src/services/embed-keys.ts:146

 * Revoke an embed key by its Convex document ID.
 *
 * Unlike `revokeApiKey`, this does not bust the edge validation cache: there is
 * no ownership-checked invalidation route for `embedKeys` yet, so a revoked key
 * keeps validating for at most the 60s `CACHE_TTL_SECONDS` in
 * `server/_shared/embed-key.ts`.
 *
 * A map frame is slower still: it already holds a `wmg_` grant good for up to
 * `EMBED_GRANT_TTL_MS` (30 minutes), and revocation only stops the NEXT mint.
 * The UI copy states both windows rather than promising one.
 */
export async function revokeEmbedKey(keyId: string): Promise<void> {
  const userId = getCurrentClerkUser()?.id;
  if (!userId) throw new Error('Sign in to revoke embed keys.');

  const [client, api] = await Promise.all([getConvexClient(), getConvexApi()]);
  if (!client || !api) throw new Error('Convex unavailable');
  if (!await waitForConvexAuthForUser(userId)) {
    throw new Error('Account changed while revoking the embed key. Try again.');
  }

  await settleAccountOperation(
    userId,
    'revoking the embed key',
    () => client.mutation((api as any).embedKeys.revokeEmbedKey, { keyId }),
  );
  assertAccountStillCurrent(userId, 'revoking the embed key');
}

View on GitHub (pinned to 7d06c8633d)