koala73/worldmonitor · error
Sign in to create an embed key.
Error message
Sign in to create an embed key.
What it means
createEmbedKey requires an authenticated Clerk user; it reads getCurrentClerkUser()?.id and throws this error when there is none. The key creation flow (generate plaintext, hash, Convex mutation) is always scoped to a user, so an anonymous session cannot proceed.
Solutions
- Sign in via Clerk before attempting to create an embed key.
- Gate the embed-key creation UI on the Clerk auth state (show a sign-in prompt until isSignedIn).
- Await Clerk session hydration (useUser/isLoaded equivalent) before invoking createEmbedKey.
- Verify the Clerk provider wraps the component so getCurrentClerkUser() can resolve.
Example fix
// before
await createEmbedKey(name);
// after
const { isSignedIn, isLoaded } = useClerkUser();
if (!isLoaded) return; // wait for hydration
if (!isSignedIn) { showSignInPrompt(); return; }
await createEmbedKey(name); Defensive patterns
Strategy: validation
Validate before calling
const userId = getCurrentClerkUser()?.id;
if (!userId) { showSignInPrompt(); return; }
await createEmbedKey(name); Type guard
const isSignedIn = (): boolean => typeof getCurrentClerkUser()?.id === 'string';
Try / catch
try {
await createEmbedKey(name);
} catch (e) {
if (e.message === 'Sign in to create an embed key.') showSignInModal();
else throw e;
} Prevention
- Gate key-management UI on Clerk isSignedIn and isLoaded.
- Await Clerk session hydration before offering create actions.
- Ensure the Clerk provider wraps the whole app.
When it happens
Trigger: Calling createEmbedKey(name) while the user is signed out, the Clerk session has not yet loaded (user is null), or the Clerk provider failed to initialize so no user id is available.
Common situations: Embed-key UI reachable before Clerk finishes loading its session; user's session expired and was silently signed out; embedding the app without the Clerk provider configured; calling createEmbedKey from code that runs before auth hydration.
Related errors
- UNAUTHENTICATED
- Authentication unavailable while loading MCP clients. Try ag
- Sign in to revoke MCP clients.
- Not authenticated
- Authentication unavailable while loading Business Pro seats.
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/94de13aac6d69ae0.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/embed-keys.ts:83
/**
* The display prefix stored alongside the hash.
*
* Nine characters — `wme_` plus five hex — because Convex validates it against
* `/^wme_[a-f0-9]{5}$/`. `api-keys.ts` slices eight for `wm_` + five; the
* longer scheme prefix is the whole difference, so this cannot be shared as a
* constant without one of the two silently taking the other's length.
*/
function embedKeyPrefix(plaintext: string): string {
return plaintext.slice(0, 9);
}
/**
* Create a new embed key for the current user.
* Returns the full plaintext key (shown once) and metadata.
*/
export async function createEmbedKey(name: string): Promise<CreateEmbedKeyResult> {
const userId = getCurrentClerkUser()?.id;
if (!userId) throw new Error('Sign in to create an embed key.');
const plaintext = generateEmbedKey();
const keyPrefix = embedKeyPrefix(plaintext);
const keyHash = await sha256Hex(plaintext);
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 creating the embed key. Try again.');
}
const result = await settleAccountOperation(
userId,
'creating the embed key',
() => client.mutation(
(api as any).embedKeys.createEmbedKey,
{ name: name.trim(), keyPrefix, keyHash },
),View on GitHub (pinned to 7d06c8633d)