sipeed/picoclaw · critical
failed to generate state: %v
Error message
failed to generate state: %v
What it means
Returned as HTTP 500 by POST /api/oauthLogin (browser method) when auth.GenerateState fails. GenerateState reads 32 bytes from crypto/rand and hex-encodes them; like the PKCE failure, it only fails when the system CSPRNG is inaccessible. It is the same class of environmental failure as error 966, one call later in the same handler.
Source
Thrown at web/backend/api/oauth.go:284
"expires_at": flow.ExpiresAt.Format(time.RFC3339),
})
return
case oauthMethodBrowser:
cfg, err := oauthConfigForProvider(provider)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
pkce, err := oauthGeneratePKCE()
if err != nil {
http.Error(w, fmt.Sprintf("failed to generate PKCE: %v", err), http.StatusInternalServerError)
return
}
state, err := oauthGenerateState()
if err != nil {
http.Error(w, fmt.Sprintf("failed to generate state: %v", err), http.StatusInternalServerError)
return
}
redirectURI := buildOAuthRedirectURI(r)
authURL := oauthBuildAuthorizeURL(cfg, pkce, state, redirectURI)
now := oauthNow()
flow := &oauthFlow{
ID: newOAuthFlowID(),
Provider: provider,
Method: method,
Status: oauthFlowPending,
CreatedAt: now,
UpdatedAt: now,
ExpiresAt: now.Add(oauthBrowserFlowTTL),
CodeVerifier: pkce.CodeVerifier,
OAuthState: state,
RedirectURI: redirectURI,View on GitHub (pinned to 49183d7e8d)
Solutions
- Test the CSPRNG in the backend's exact environment (a Go one-liner with crypto/rand or reading /dev/urandom).
- Fix the sandbox/kernel (allow getrandom, add virtio-rng to the VM, mount /dev properly) and retry the browser login.
- Treat repeated occurrences as an infrastructure incident: this error means the host cannot generate secure randomness at all, which breaks every auth path, not just this one.
- Workaround for users: complete login with method "token" if available for the provider (openai, anthropic).
Defensive patterns
Strategy: fallback
Try / catch
const res = await startBrowserLogin(provider);
if (res.status === 500 && /generate state/i.test((await res.json()).message ?? '')) {
return startTokenLogin(provider); // CSPRNG unavailable — use a method that needs no rand
}
return res; Prevention
- Same class as PKCE failure: check the runtime can read /dev/urandom before deploying browser login.
- Give VMs an RNG device (virtio-rng) so entropy is available at boot.
- Alert on this error: a broken CSPRNG undermines every auth flow on the host.
When it happens
Trigger: POST /api/oauth/login {"provider":"openai","method":"browser"} on a runtime where crypto/rand.Read errors (seccomp-blocked getrandom, early-boot entropy starvation, broken /dev/urandom). If PKCE succeeded but this fails, the entropy source died between the two calls.
Common situations: Hardened container runtimes, VMs without RNG devices, chroot environments without /dev mounted properly.
Related errors
- failed to generate PKCE: %v
- credential: failed to generate salt: %w
- token login failed: %v
- failed to request device code: %v
- failed to delete credential: %v
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/969de6e4a97910ae.
Report an issue: GitHub.