{"record":{"id":"3fa6fd9d83576f64","repo":"koala73/worldmonitor","slug":"convex-unavailable-embed-keys","errorCode":null,"errorMessage":"Convex unavailable","messagePattern":"Convex unavailable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/embed-keys.ts","lineNumber":90,"sourceCode":" */\nfunction embedKeyPrefix(plaintext: string): string {\n  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. */","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/src/services/embed-keys.ts#L72-L108","documentation":"createEmbedKey needs both a Convex client and the generated Convex API reference; Promise.all resolves both and if either is null/undefined (Convex not configured or client initialization failed) this error is thrown. It signals the app's persistence backend is unavailable, not an auth or input problem.","triggerScenarios":"getConvexClient() or getConvexApi() returns null — e.g. NEXT_PUBLIC/VITE Convex URL env var missing, ConvexProvider not mounted, or client construction failed during boot.","commonSituations":"Deploying without the Convex deployment URL environment variable set; running locally without `convex dev`; a build that tree-shook or misconfigured the Convex provider; Convex deployment deleted or renamed.","solutions":["Verify the Convex URL environment variable is set in the deployment/localhost env and restart.","Ensure the ConvexProvider is mounted at the app root so getConvexClient() can resolve.","Run `convex dev` / redeploy the Convex functions and confirm the generated api reference matches.","Add a startup check that surfaces a clear configuration error if Convex is unset."],"exampleFix":"// before\nconst [client, api] = await Promise.all([getConvexClient(), getConvexApi()]);\nif (!client || !api) throw new Error('Convex unavailable');\n// after\nconst convexUrl = import.meta.env.VITE_CONVEX_URL;\nif (!convexUrl) throw new Error('VITE_CONVEX_URL is not configured');\nconst [client, api] = await Promise.all([getConvexClient(), getConvexApi()]);\nif (!client || !api) throw new Error('Convex unavailable — check provider mounting');","handlingStrategy":"validation","validationCode":"if (!import.meta.env.VITE_CONVEX_URL) throw new Error('Convex URL env var is not set');\nconst client = getConvexClient();\nif (!client) throw new Error('ConvexProvider not mounted');","typeGuard":"const convexReady = (): boolean => getConvexClient() != null && getConvexApi() != null;","tryCatchPattern":"try {\n  await createEmbedKey(name);\n} catch (e) {\n  if (e.message === 'Convex unavailable') {\n    showError('Backend not configured — check the Convex deployment URL.');\n  } else throw e;\n}","preventionTips":["Assert required Convex env vars at boot with a clear failure message.","Mount ConvexProvider at the app root in every entry point.","Smoke-test Convex connectivity on app startup."],"tags":["convex","configuration","missing-dependency","embed-keys"],"backgroundTag":"missing-env-var","analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-09-15T16:44:39.439Z","contentChangedAt":"2026-09-15T16:44:39.439Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}