{"record":{"id":"f8ba0419005b6159","repo":"chatboxai/chatbox","slug":"email-required","errorCode":null,"errorMessage":"email required","messagePattern":"email required","errorType":"exception","errorClass":"VibedropEmailRequiredError","httpStatus":null,"severity":"error","filePath":"src/renderer/packages/remote.ts","lineNumber":1025,"sourceCode":"      {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json',\n          ...(await getChatboxHeaders()),\n        },\n      },\n      // No retry: issue-key is a fast upsert; email_required is a deterministic\n      // 400 and retrying it just wastes a round-trip (afetch retries all non-2xx).\n      { retry: 0 }\n    )\n    const json: { vd_key: string; tier: string } = await res.json()\n    return { vdKey: json.vd_key, tier: json.tier }\n  } catch (e) {\n    if (e instanceof ApiError && e.responseBody) {\n      try {\n        const parsed = JSON.parse(e.responseBody)\n        if (parsed?.error?.code === 'email_required') {\n          throw new VibedropEmailRequiredError('email required')\n        }\n      } catch (parseErr) {\n        if (parseErr instanceof VibedropEmailRequiredError) throw parseErr\n      }\n    }\n    throw e\n  }\n}\n\nexport interface UserLicense {\n  id: number\n  key: string\n  status: string\n  platform: string\n  product_name: string\n  plan?: ChatboxAIPlanType\n  payment_type: string\n  image_usage: number","sourceCodeStart":1007,"sourceCodeEnd":1043,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/renderer/packages/remote.ts#L1007-L1043","documentation":"Thrown as VibedropEmailRequiredError when the vibedrop key-issuance endpoint returns an error whose parsed body has error.code === 'email_required'. It signals that the account must have a verified email before a vd_key can be issued. The rethrow unwraps the deterministic 400 into a typed, user-actionable error.","triggerScenarios":"Calling the vibedrop issue-key flow for an account that has no email on record; the server responds 400 with {error:{code:'email_required'}}. The catch inspects e.responseBody, parses JSON, and rethrows VibedropEmailRequiredError('email required').","commonSituations":"New account created via an OAuth provider that did not share an email; account email was removed/never verified; the issue-key endpoint tightened its email requirement in a backend release.","solutions":["Collect and verify the user's email on the account, then retry the vibedrop flow.","If using OAuth login, ensure the email scope is granted so the provider returns an email.","Handle VibedropEmailRequiredError in the UI to prompt for email instead of showing a generic failure."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function accountHasEmail(): boolean {\n  return !!authInfoStore.getState().email\n}\nif (!accountHasEmail()) {\n  // prompt for email before requesting a vd_key\n}","typeGuard":"function isVibedropEmailRequiredError(e: unknown): e is VibedropEmailRequiredError {\n  return e instanceof VibedropEmailRequiredError\n}","tryCatchPattern":"try {\n  await requestVdKey()\n} catch (e) {\n  if (e instanceof VibedropEmailRequiredError) {\n    // open email-collection flow, then retry\n  }\n}","preventionTips":["Collect/verify email during onboarding.","Request email scope on OAuth login.","Handle this typed error distinctly from generic API errors."],"tags":["vibedrop","auth","email","validation"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}