{"record":{"id":"9bcd5ca692a5f1ae","repo":"sipeed/picoclaw","slug":"failed-to-generate-pkce-v","errorCode":null,"errorMessage":"failed to generate PKCE: %v","messagePattern":"failed to generate PKCE: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"critical","filePath":"web/backend/api/oauth.go","lineNumber":279,"sourceCode":"\t\t\t\"method\":     method,\n\t\t\t\"flow_id\":    flow.ID,\n\t\t\t\"user_code\":  flow.UserCode,\n\t\t\t\"verify_url\": flow.VerifyURL,\n\t\t\t\"interval\":   flow.Interval,\n\t\t\t\"expires_at\": flow.ExpiresAt.Format(time.RFC3339),\n\t\t})\n\t\treturn\n\n\tcase oauthMethodBrowser:\n\t\tcfg, err := oauthConfigForProvider(provider)\n\t\tif err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\n\t\tpkce, err := oauthGeneratePKCE()\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to generate PKCE: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\tstate, err := oauthGenerateState()\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to generate state: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\tredirectURI := buildOAuthRedirectURI(r)\n\t\tauthURL := oauthBuildAuthorizeURL(cfg, pkce, state, redirectURI)\n\n\t\tnow := oauthNow()\n\t\tflow := &oauthFlow{\n\t\t\tID:           newOAuthFlowID(),\n\t\t\tProvider:     provider,\n\t\t\tMethod:       method,\n\t\t\tStatus:       oauthFlowPending,\n\t\t\tCreatedAt:    now,","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/web/backend/api/oauth.go#L261-L297","documentation":"Returned as HTTP 500 by POST /api/oauth/login (browser method) when auth.GeneratePKCE fails. GeneratePKCE does a single crypto/rand.Read of 64 bytes and builds the PKCE verifier/challenge; on Linux it fails only when the kernel CSPRNG is unavailable (getrandom(2) error), which is essentially a broken or massively restricted runtime. No input from the request can cause it.","triggerScenarios":"POST /api/oauth/login {\"provider\":\"openai\",\"method\":\"browser\"} on a host where crypto/rand.Read returns an error — e.g. a seccomp/container profile blocking getrandom, an extremely early-boot VM before the entropy pool is initialized, or a broken /dev/urandom.","commonSituations":"Over-restrictive gVisor/Firecracker/seccomp sandboxes; exotic embedded kernels; virtually never on normal Linux/macOS dev machines or standard Docker.","solutions":["Verify the CSPRNG from inside the same environment: head -c 32 /dev/urandom | xxd (or a tiny Go program doing crypto/rand.Read).","Loosen the container/sandbox profile so getrandom(2)//dev/urandom is permitted.","On VMs that boot before entropy init, ensure the VM has virtio-rng or wait a few seconds after boot and retry the login request.","If the environment fundamentally cannot provide a CSPRNG, use token login instead (method \"token\"), which does not call rand during the request."],"exampleFix":"// before: sandbox blocks getrandom\nPOST /api/oauth/login {\"provider\":\"openai\",\"method\":\"browser\"}\n// -> 500 failed to generate PKCE: crypto/rand failed\n\n// after: docker run --security-opt seccomp=unconfined ... # or fix the profile to allow getrandom\nPOST /api/oauth/login {\"provider\":\"openai\",\"method\":\"browser\"}\n// -> 200 {\"auth_url\":\"https://auth.openai.com/...\"}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"const res = await startBrowserLogin(provider);\nif (res.status === 500) {\n  const { message } = await res.json();\n  if (/generate PKCE/i.test(message ?? '')) {\n    // host CSPRNG is broken: fall back to token login (no randomness needed per request)\n    return startTokenLogin(provider);\n  }\n  throw new Error(message);\n}","preventionTips":["Verify crypto randomness works in the deployment environment before enabling browser OAuth (head -c 32 /dev/urandom).","Do not over-restrict container seccomp profiles — getrandom(2) must be allowed.","Treat PKCE/state generation failures as infrastructure alerts, not user errors."],"tags":["oauth","http-500","pkce","crypto-rand","environment"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}