{"record":{"id":"8729d8e8cd80a25a","repo":"chatboxai/chatbox","slug":"failed-to-send-login-code","errorCode":null,"errorMessage":"Failed to send login code","messagePattern":"Failed to send login code","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/renderer/routes/settings/provider/chatbox-ai/-components/useLogin.ts","lineNumber":116,"sourceCode":"      return false\n    }\n\n    try {\n      setLoginState('sending_code')\n      setLoginError('')\n      setCode('')\n\n      const result = await sendEmailLoginCode({\n        email: trimmedEmail,\n        lang: getLanguagePath(language),\n      })\n\n      if (requestEpoch !== requestEpochRef.current) {\n        return false\n      }\n\n      if (result !== 'sent') {\n        throw new Error('Failed to send login code')\n      }\n\n      setLoginState('code_sent')\n      setHasEnteredCodeStep(true)\n      setCountdown(EMAIL_CODE_RESEND_SECONDS)\n      return true\n    } catch (error: unknown) {\n      if (requestEpoch !== requestEpochRef.current) {\n        return false\n      }\n\n      console.error('Failed to send login code:', error)\n      const errorMsg = getReadableErrorMessage(error, t('Failed to send login code'))\n      setLoginError(errorMsg)\n      setLoginState('error')\n      return false\n    }\n  }, [email, language, t])","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/renderer/routes/settings/provider/chatbox-ai/-components/useLogin.ts#L98-L134","documentation":"Thrown by sendCode when sendEmailLoginCode resolves with any value other than the literal 'sent'. The login-code endpoint is expected to acknowledge success with 'sent'; any other payload is treated as a rejection. The throw is caught immediately and converted to a user-facing loginError, so it is a control-flow signal more than a crash.","triggerScenarios":"sendEmailLoginCode returns a non-'sent' string — backend-reported reasons such as rate limiting, invalid/unknown email, banned account, or an undocumented status. Also fires if the endpoint payload shape changes (e.g. returns { status: 'sent' }) so the strict equality check fails.","commonSituations":"User clicks 'send code' repeatedly and hits server-side rate limiting, email is malformed in a way the client regex allowed, backend deploy changes the response contract, or the account is flagged.","solutions":["Differentiate non-'sent' values: map known backend reasons (rate_limited, invalid_email) to specific UI messages instead of a generic throw.","Confirm the sendEmailLoginCode return contract matches the backend (string 'sent' vs object).","Throttle the send button with the EMAIL_CODE_RESEND_SECONDS countdown before the request fires.","Log the actual returned value (redacted) to identify contract drift."],"exampleFix":"// before\nif (result !== 'sent') {\n  throw new Error('Failed to send login code')\n}\n// after\nif (result !== 'sent') {\n  const reason = typeof result === 'string' ? result : 'unknown'\n  throw new Error(`Failed to send login code: ${reason}`)\n}","handlingStrategy":"validation","validationCode":"const result = await sendEmailLoginCode({ email: trimmedEmail, lang: getLanguagePath(language) })\nif (result !== 'sent') {\n  // result carries the backend reason; map it before throwing\n}","typeGuard":"type SendCodeResult = 'sent' | 'rate_limited' | 'invalid_email' | 'unknown'\nfunction isSendSuccess(r: unknown): r is 'sent' {\n  return r === 'sent'\n}","tryCatchPattern":"try {\n  const result = await sendEmailLoginCode(...)\n  if (!isSendSuccess(result)) setLoginError(mapSendCodeResult(result))\n} catch (error) {\n  setLoginError(getReadableErrorMessage(error, t('Failed to send login code')))\n}","preventionTips":["Throttle the send button with EMAIL_CODE_RESEND_SECONDS before firing the request.","Map known backend reason strings to specific UI messages.","Validate email format client-side before the request."],"tags":["auth","login","email","backend-contract"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}