{"record":{"id":"c7ae6b9afb8a2d7e","repo":"sipeed/picoclaw","slug":"generating-pkce-w","errorCode":null,"errorMessage":"generating PKCE: %w","messagePattern":"generating PKCE: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/auth/oauth.go","lineNumber":94,"sourceCode":"}\n\n// GenerateState generates a random state string for OAuth CSRF protection.\nfunc GenerateState() (string, error) {\n\tbuf := make([]byte, 32)\n\tif _, err := rand.Read(buf); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn hex.EncodeToString(buf), nil\n}\n\nfunc LoginBrowser(cfg OAuthProviderConfig) (*AuthCredential, error) {\n\treturn LoginBrowserWithOptions(cfg, LoginBrowserOptions{})\n}\n\nfunc LoginBrowserWithOptions(cfg OAuthProviderConfig, opts LoginBrowserOptions) (*AuthCredential, error) {\n\tpkce, err := GeneratePKCE()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"generating PKCE: %w\", err)\n\t}\n\n\tstate, err := GenerateState()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"generating state: %w\", err)\n\t}\n\n\tredirectURI := oauthCallbackRedirectURI(cfg.Port)\n\tcallbackPort := cfg.Port\n\tvar resultCh <-chan callbackResult\n\n\tif !opts.NoBrowser {\n\t\tcallbackResultCh := make(chan callbackResult, 1)\n\t\tlistener, actualPort, err := listenOAuthCallback(cfg.Port)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"starting callback server on port %d: %w\", cfg.Port, err)\n\t\t}\n","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/auth/oauth.go#L76-L112","documentation":"GeneratePKCE() failed at pkg/auth/oauth.go:94 — crypto/rand could not fill the code-verifier buffer. On any normal Linux/macOS/Windows host this cannot happen; it indicates the OS random source is unavailable or blocked (broken container runtime, hardened seccomp blocking getrandom(2), or a replaced rand.Reader in tests).","triggerScenarios":"Running under a sandbox profile that denies getrandom(2)//dev/urandom; minimal VMs with entropy starvation at very early boot; a test or embedding that swaps rand.Reader with a failing reader.","commonSituations":"gVisor/Firecracker microVMs with restrictive syscalls; custom-built minimal containers missing /dev/urandom; extremely rare in practice.","solutions":["Treat as environmental: verify the container/VM exposes /dev/urandom and getrandom works (head -c 32 /dev/urandom)","Loosen the seccomp/sandbox profile to allow getrandom","Restart the process — entropy pool blockage at boot self-resolves","Do not add retries; if the OS RNG is broken, retrying is futile and dangerous"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := auth.LoginBrowserWithOptions(cfg, opts); err != nil {\n    if strings.Contains(err.Error(), \"generating PKCE\") {\n        // OS randomness unavailable: environmental, not retryable\n        log.Fatal(\"OS random source unavailable; check sandbox/seccomp profile\")\n    }\n    return err\n}","preventionTips":["Ensure containers/VMs expose /dev/urandom and permit getrandom(2)","Do not write retry loops around RNG failures","In tests, replace rand.Reader deliberately rather than masking failures"],"tags":["crypto","oauth","go","sandbox"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}