{"record":{"id":"50fab39f0df638cd","repo":"plandex-ai/plandex","slug":"error-validating-email-verification-50fab3","errorCode":null,"errorMessage":"Error validating email verification: ","messagePattern":"Error validating email verification: ","errorType":"http","errorClass":"http","httpStatus":500,"severity":"error","filePath":"app/server/handlers/sessions.go","lineNumber":167,"sourceCode":"\tvar req shared.VerifyEmailPinRequest\n\terr = json.Unmarshal(body, &req)\n\tif err != nil {\n\t\tlog.Printf(\"Error unmarshalling request: %v\\n\", err)\n\t\thttp.Error(w, \"Error unmarshalling request: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\treq.Email = strings.ToLower(req.Email)\n\n\t_, err = db.ValidateEmailVerification(req.Email, req.Pin)\n\n\tif err != nil {\n\t\tif err.Error() == db.InvalidOrExpiredPinError {\n\t\t\thttp.Error(w, \"Invalid or expired pin\", http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\n\t\tlog.Printf(\"Error validating email verification: %v\\n\", err)\n\t\thttp.Error(w, \"Error validating email verification: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tlog.Println(\"Successfully verified email pin\")\n}\n\n// sign in codes allow users to authenticate between different clients\n// like UI to CLI or vice versa\nfunc CreateSignInCodeHandler(w http.ResponseWriter, r *http.Request) {\n\tlog.Println(\"Received request for CreateSignInCodeHandler\")\n\n\tauth := Authenticate(w, r, true)\n\n\tif auth == nil {\n\t\treturn\n\t}\n\n\t// create pin - 6 alphanumeric characters","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/sessions.go#L149-L185","documentation":"This error is returned when db.ValidateEmailVerification fails with an error that is NOT the known InvalidOrExpiredPinError sentinel. The handler responds with HTTP 500 prefixed 'Error validating email verification: '. It signals an unexpected backend problem during the lookup — most commonly a database connectivity or query failure — rather than a bad PIN.","triggerScenarios":"POST to verify-email-pin where the underlying DB query inside db.ValidateEmailVerification errors: database unreachable, scan/row iteration failure, schema mismatch, or context/timeout cancellation.","commonSituations":"Postgres down or restarting during the request; migration drift making the query fail; connection pool exhausted under load; network partition between app and database in containerized deployments.","solutions":["Check the log for the wrapped error to see the actual DB failure","Verify database health and connectivity (DATABASE_URL, pool limits)","Run migrations to fix any schema drift","Retry the request after the database recovers"],"exampleFix":"// before\n_, err = db.ValidateEmailVerification(req.Email, req.Pin)\nif err != nil {\n\thttp.Error(w, \"Error validating email verification: \"+err.Error(), http.StatusInternalServerError)\n}\n// after: add a bounded retry for transient DB failures\nvar rec *shared.VerifyEmailPinResponse\nfor i := 0; i < 3; i++ {\n\trec, err = db.ValidateEmailVerification(req.Email, req.Pin)\n\tif err == nil || err.Error() == db.InvalidOrExpiredPinError {\n\t\tbreak\n\t}\n\ttime.Sleep(200 * time.Millisecond)\n}","handlingStrategy":"retry","validationCode":"// before the flow, confirm the backend is healthy\nresp, err := http.Get(baseURL + \"/health\")\nif err != nil || resp.StatusCode != 200 {\n\treturn fmt.Errorf(\"backend unavailable, postpone pin verification: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"// distinguish expected invalid-pin from unexpected 500\nif resp.StatusCode == http.StatusInternalServerError {\n\tvar msg string\n\tjson.NewDecoder(resp.Body).Decode(&msg)\n\tif strings.HasPrefix(msg, \"Error validating email verification\") {\n\t\t// transient DB failure: back off and retry\n\t\ttime.Sleep(2 * time.Second)\n\t\treturn retryVerify(email, pin)\n\t}\n}","preventionTips":["Monitor database health and connection-pool saturation","Keep migrations in sync with deployed code","Add bounded retries for transient DB errors in the handler","Alert on elevated 500 rates from the verify-pin endpoint"],"tags":["database","http-500","go","pin-validation"],"backgroundTag":"database-query-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}