{"record":{"id":"e79848e2534e965c","repo":"plandex-ai/plandex","slug":"error-generating-random-pin","errorCode":null,"errorMessage":"Error generating random pin: ","messagePattern":"Error generating random pin: ","errorType":"http","errorClass":"http","httpStatus":500,"severity":"error","filePath":"app/server/handlers/sessions.go","lineNumber":90,"sourceCode":"\n\tif req.RequireUser && !hasAccount {\n\t\tlog.Printf(\"User not found for email: %v\\n\", req.Email)\n\t\thttp.Error(w, \"User not found\", http.StatusNotFound)\n\t\treturn\n\t} else if req.RequireNoUser && hasAccount {\n\t\tlog.Printf(\"User already exists for email: %v\\n\", req.Email)\n\t\thttp.Error(w, \"User already exists\", http.StatusConflict)\n\t\treturn\n\t}\n\n\tvar res shared.CreateEmailVerificationResponse\n\n\tif !(os.Getenv(\"GOENV\") == \"development\" && os.Getenv(\"LOCAL_MODE\") == \"1\") {\n\t\t// create pin - 6 alphanumeric characters\n\t\tpinBytes, err := shared.GetRandomAlphanumeric(6)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Error generating random pin: %v\\n\", err)\n\t\t\thttp.Error(w, \"Error generating random pin: \"+err.Error(), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\t// get sha256 hash of pin\n\t\thashBytes := sha256.Sum256(pinBytes)\n\t\tpinHash := hex.EncodeToString(hashBytes[:])\n\n\t\t// create verification\n\t\terr = db.CreateEmailVerification(req.Email, req.UserId, pinHash)\n\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Error creating email verification: %v\\n\", err)\n\t\t\thttp.Error(w, \"Error creating email verification: \"+err.Error(), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\terr = email.SendVerificationEmail(req.Email, string(pinBytes))\n","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/sessions.go#L72-L108","documentation":"CreateEmailVerificationHandler returns HTTP 500 'Error generating random pin: <err>' when shared.GetRandomAlphanumeric(6) fails while creating the 6-character verification PIN. This generator wraps crypto/rand and fails only when the OS cryptographic RNG is unavailable or exhausted, an extremely rare condition (e.g., getrandom(2) syscall failure). This is a server-side internal error, not something the client caused.","triggerScenarios":"Calling the endpoint with GOENV != 'development' or LOCAL_MODE != '1' (the local-mode branch skips PIN generation) while the crypto/rand source fails - e.g., getrandom syscall returning EAGAIN/EINTR loops exhausted, or a container/host with a broken entropy setup.","commonSituations":"Running the server in a restricted/hardened container where /dev RNG or getrandom is blocked by seccomp rules; heavily stripped minimal Docker images missing RNG device setup; kernel-level entropy exhaustion on old kernels (pre-3.17 without getrandom); sandboxed CI environments.","solutions":["Retry the request - crypto/rand failures are typically transient; a second call usually succeeds.","Check the full server log line 'Error generating random pin: <err>' to see the underlying crypto/rand error and address it specifically.","If running in a container, verify the kernel is >= 3.17 and no seccomp/apparmor profile blocks the getrandom syscall.","Ensure /dev/urandom (and /dev/random) exist and are accessible inside the container; use a standard base image rather than a heavily stripped one.","For local development, set GOENV=development and LOCAL_MODE=1 to bypass PIN generation entirely (local-mode branch)."],"exampleFix":"// before (server env, broken RNG)\nGOENV=production LOCAL_MODE=0 ./plandex-server\n// after (temporary local workaround while RNG issue is investigated)\nGOENV=development LOCAL_MODE=1 ./plandex-server","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// server-side callers / ops: retry on 500 whose body mentions random pin\nfor attempt := 0; attempt < 3; attempt++ {\n    resp, err := http.Post(url, \"application/json\", body)\n    if err != nil { continue }\n    if resp.StatusCode == http.StatusInternalServerError && strings.Contains(readBody(resp), \"Error generating random pin\") {\n        time.Sleep(backoff(attempt)) // transient crypto/rand failure\n        continue\n    }\n    break\n}","preventionTips":["Use a standard container base image; avoid stripped images that break RNG device setup.","Ensure kernel >= 3.17 so the getrandom syscall is available.","Check seccomp/AppArmor policies don't block getrandom or /dev/urandom access.","Set GOENV=development and LOCAL_MODE=1 in local dev to skip PIN generation entirely.","Alert on any occurrence of 'Error generating random pin' in server logs - it signals host-level RNG problems, not app bugs."],"tags":["http-500","internal-error","crypto-rand","email-verification","pin-generation"],"backgroundTag":"crypto-rand-failure","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"}