{"record":{"id":"d90c85c851c56178","repo":"apache/answer","slug":"captcha-not-exist","errorCode":null,"errorMessage":"captcha not exist","messagePattern":"captcha not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/repo/captcha/captcha.go","lineNumber":106,"sourceCode":"}\n\n// SetCaptcha set captcha to cache\nfunc (cr *captchaRepo) SetCaptcha(ctx context.Context, key, captcha string) (err error) {\n\terr = cr.data.Cache.SetString(ctx, key, captcha, 6*time.Minute)\n\tif err != nil {\n\t\terr = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()\n\t}\n\treturn\n}\n\n// GetCaptcha get captcha from cache\nfunc (cr *captchaRepo) GetCaptcha(ctx context.Context, key string) (captcha string, err error) {\n\tcaptcha, exist, err := cr.data.Cache.GetString(ctx, key)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif !exist {\n\t\treturn \"\", fmt.Errorf(\"captcha not exist\")\n\t}\n\treturn captcha, nil\n}\n\nfunc (cr *captchaRepo) DelCaptcha(ctx context.Context, key string) (err error) {\n\terr = cr.data.Cache.Del(ctx, key)\n\tif err != nil {\n\t\tlog.Debug(err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":88,"sourceCodeEnd":118,"githubUrl":"https://github.com/apache/answer/blob/3b9f1370612e690a0b7f230f05e688930db4c6d3/internal/repo/captcha/captcha.go#L88-L118","documentation":"Returned by GetCaptcha when the cache holds no value for the given key: Cache.GetString reports exist=false and the repo converts that into this error. Captcha values are stored with a TTL, so a missing entry usually means the captcha expired or the key was deleted/never set.","triggerScenarios":"Looking up a captcha by a key that was never Set, a key already consumed by DelCaptcha after verification, or one that expired from the cache.","commonSituations":"User takes longer than the captcha TTL to submit the form; user double-submits (first verify deletes the key); Redis restarted/flushed between issuance and verification; load-balanced deployments pointing at different cache instances.","solutions":["Return a 'captcha expired, please refresh' response to the user instead of a 500, and issue a new captcha.","Increase the captcha TTL in cache configuration if it expires too quickly for real users.","Verify all app instances share the same Redis/cache backend.","Deliver the same cache key used at SetCaptcha time (no key mangling/prefix mismatch)."],"exampleFix":"// before\ncaptcha, exist, err := cr.data.Cache.GetString(ctx, key)\nif !exist {\n    return \"\", fmt.Errorf(\"captcha not exist\")\n}\n// after\ncaptcha, exist, err := cr.data.Cache.GetString(ctx, key)\nif err != nil {\n    return \"\", err\n}\nif !exist {\n    return \"\", ErrCaptchaExpired // caller maps to 4xx 'captcha expired, refresh'\n}","handlingStrategy":"try-catch","validationCode":"// before submit: ensure a captcha was issued and is recent\nif captchaKey == \"\" || time.Since(captchaIssuedAt) > captchaTTL {\n    // fetch a fresh captcha instead of verifying a stale one\n    return errors.New(\"captcha missing or likely expired, request a new one\")\n}","typeGuard":"func captchaUsable(key string, issuedAt time.Time, ttl time.Duration) bool {\n    return key != \"\" && time.Since(issuedAt) < ttl\n}","tryCatchPattern":"answer, err := captchaRepo.GetCaptcha(ctx, key)\nif err != nil {\n    if strings.Contains(err.Error(), \"captcha not exist\") {\n        return http.StatusBadRequest, \"captcha expired, please refresh\"\n    }\n    return http.StatusInternalServerError, err.Error()\n}","preventionTips":["Set a captcha TTL comfortably longer than typical form completion time.","Delete the captcha key only after successful verification (single-use).","Ensure all instances point at the same Redis cache (no split backends).","Return a user-facing 'expired' message rather than a server error."],"tags":["cache","captcha","expiration"],"backgroundTag":"cache-key-not-found","analyzedSha":"3b9f1370612e690a0b7f230f05e688930db4c6d3","analyzedAt":"2026-09-05T18:18:39.533Z","contentChangedAt":"2026-09-05T18:18:39.533Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}