{"record":{"id":"bee6fad47f8a0ea1","repo":"Billionmail/BillionMail","slug":"failed-to-get-validate-code-w","errorCode":null,"errorMessage":"failed to get validate code: %w","messagePattern":"failed to get validate code: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/controller/rbac/rbac_v1_get_validate_code.go","lineNumber":25,"sourceCode":"\t\"fmt\"\n\t\"github.com/gogf/gf/v2/frame/g\"\n\n\t\"billionmail-core/api/rbac/v1\"\n)\n\nfunc (c *ControllerV1) GetValidateCode(ctx context.Context, req *v1.GetValidateCodeReq) (res *v1.GetValidateCodeRes, err error) {\n\tres = &v1.GetValidateCodeRes{}\n\n\tclientIp := g.RequestFromCtx(ctx).GetClientIp()\n\n\tcacheKey := fmt.Sprintf(\"USER_LOGIN_RETRIES:%s\", clientIp)\n\n\tres.Data.LoginRetries, res.Data.MustValidateCode = public.GetCache(cacheKey).(int)\n\tres.Data.MaxLoginRetries = 5\n\tres.Data.ValidateCodeId, res.Data.ValidateCodeBase64, err = rbac.GetCaptcha()\n\n\tif err != nil {\n\t\terr = fmt.Errorf(\"failed to get validate code: %w\", err)\n\t\treturn\n\t}\n\n\tres.SetSuccess(public.LangCtx(ctx, \"Success\"))\n\n\treturn\n}\n","sourceCodeStart":7,"sourceCodeEnd":33,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/controller/rbac/rbac_v1_get_validate_code.go#L7-L33","documentation":"The login page calls GetValidateCode to fetch a captcha image; this error wraps any failure from rbac.GetCaptcha(), which generates the captcha ID and a base64 PNG. The wrapped cause tells you whether generation (image/font/code store) or persistence of the captcha failed. Users cannot get a captcha and thus cannot log in when a captcha is required.","triggerScenarios":"GET validate-code when GetCaptcha() fails: its internal captcha store (Redis/cache) is down, image generation fails, or captcha library misconfiguration after a dependency change.","commonSituations":"Redis unavailable in the deployment; captcha dependency version change breaking image rendering; disk/font issues in minimal container images.","solutions":["Check the cache/redis backend used by the captcha service is running","Look at logs for the wrapped inner error to identify generation vs storage failure","Restart the app after restoring the captcha store","If captchas are not needed, ensure the login-retry counter is below the threshold so mustValidateCode stays false"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// check whether captcha is required first\nconst status = await api.getLoginState();\nif (!status.data.mustValidateCode) skipCaptcha();","typeGuard":null,"tryCatchPattern":"try {\n  const code = await api.getValidateCode();\n} catch (e) {\n  if (e.message.includes('validate code')) {\n    await delay(1000);\n    return getValidateCode(); // retry, transient store issue\n  }\n}","preventionTips":["Keep Redis/cache backend healthy (docker healthchecks)","Pin captcha library versions in go.mod","Alert on captcha generation failures","Cache failure counters to avoid hammering the endpoint"],"tags":["captcha","validation-code","login","redis"],"backgroundTag":"captcha-generation-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}