sipeed/picoclaw · error
provider %q does not support browser oauth
Error message
provider %q does not support browser oauth
What it means
Returned as HTTP 400 by POST /api/oauth/login (browser method) via oauthConfigForProvider: only "openai" and "google-antigravity" have browser OAuth configs (auth.OpenAIOAuthConfig / auth.GoogleAntigravityOAuthConfig); the default branch of the switch produces this message. With the current method matrix it is effectively a defensive guard, because isOAuthMethodSupported already rejects browser login for anthropic earlier with error 961 — you can only reach 965 if the matrix and the config switch have drifted (e.g. browser was added to anthropic's methods without adding a config).
Source
Thrown at web/backend/api/oauth.go:273
h.storeOAuthFlow(flow)
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]any{
"status": "ok",
"provider": provider,
"method": method,
"flow_id": flow.ID,
"user_code": flow.UserCode,
"verify_url": flow.VerifyURL,
"interval": flow.Interval,
"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()View on GitHub (pinned to 49183d7e8d)
Solutions
- If you are a caller: this should normally be unreachable — first check that the method matrix really allows browser for the provider, then upgrade/redeploy the backend so matrix and config agree.
- If you are modifying the backend: every provider you add to oauthProviderMethods[provider] with "browser" must also get a case in oauthConfigForProvider returning an auth.OAuthProviderConfig.
- Add a unit test asserting each provider in oauthProviderMethods with browser support passes oauthConfigForProvider without error, so the drift is caught at build time.
Example fix
// before (web/backend/api/oauth.go)
var oauthProviderMethods = map[string][]string{
oauthProviderAnthropic: {oauthMethodBrowser, oauthMethodToken}, // browser advertised...
}
func oauthConfigForProvider(provider string) (auth.OAuthProviderConfig, error) {
switch provider {
case oauthProviderOpenAI: return auth.OpenAIOAuthConfig(), nil
case oauthProviderGoogleAntigravity: return auth.GoogleAntigravityOAuthConfig(), nil
default: return auth.OAuthProviderConfig{}, fmt.Errorf("provider %q does not support browser oauth", provider) // ...but no config
}
}
// after: add the matching case
func oauthConfigForProvider(provider string) (auth.OAuthProviderConfig, error) {
switch provider {
case oauthProviderOpenAI: return auth.OpenAIOAuthConfig(), nil
case oauthProviderGoogleAntigravity: return auth.GoogleAntigravityOAuthConfig(), nil
case oauthProviderAnthropic: return auth.AnthropicOAuthConfig(), nil
default: return auth.OAuthProviderConfig{}, fmt.Errorf("provider %q does not support browser oauth", provider)
}
} Defensive patterns
Strategy: validation
Validate before calling
const BROWSER_CAPABLE = new Set(['openai', 'google-antigravity']);
function assertBrowserSupported(provider) {
if (!BROWSER_CAPABLE.has(provider)) throw new Error(`provider ${JSON.stringify(provider)} does not support browser oauth`);
} Type guard
function supportsBrowserOauth(provider) {
return ['openai', 'google-antigravity'].includes(provider);
} Prevention
- Only offer 'browser' for providers whose methods list (from /api/oauth/providers) includes it.
- If you fork the backend, keep oauthProviderMethods and oauthConfigForProvider in sync — add a test that every browser-capable provider returns a config.
When it happens
Trigger: POST /api/oauth/login {"provider":"anthropic","method":"browser"} in a build where oauthProviderMethods lists browser for anthropic but oauthConfigForProvider still has no anthropic case; or any new provider added to the methods map with browser support but no branch in oauthConfigForProvider.
Common situations: Local fork or PR that adds a provider's browser method but forgets the config switch; regression after refactoring oauthProviderMethods; hitting an older backend with a newer frontend that assumes a method exists.
Related errors
- unsupported login method
- flow does not support polling
- unsupported provider %q
- unsupported login method %q for provider %q
- token is required
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/bec44c8fa19c1103.
Report an issue: GitHub.