sipeed/picoclaw · warning
unsupported login method
Error message
unsupported login method
What it means
Returned as HTTP 400 by the default branch of the method switch in POST /api/oauth/login. It is a defensive fallback: every method accepted by isOAuthMethodSupported (browser, device_code, token) has an explicit case, so with a consistent build this branch is unreachable. Hitting it means the binary's method matrix and switch have diverged — someone added a method string to oauthProviderMethods without implementing its case (or vice versa in tests).
Source
Thrown at web/backend/api/oauth.go:317
ExpiresAt: now.Add(oauthBrowserFlowTTL),
CodeVerifier: pkce.CodeVerifier,
OAuthState: state,
RedirectURI: redirectURI,
}
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,
"auth_url": authURL,
"expires_at": flow.ExpiresAt.Format(time.RFC3339),
})
return
default:
http.Error(w, "unsupported login method", http.StatusBadRequest)
}
}
func (h *Handler) handleGetOAuthFlow(w http.ResponseWriter, r *http.Request) {
flowID := strings.TrimSpace(r.PathValue("id"))
if flowID == "" {
http.Error(w, "missing flow id", http.StatusBadRequest)
return
}
flow, ok := h.getOAuthFlow(flowID)
if !ok {
http.Error(w, "flow not found", http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(flowToResponse(flow))View on GitHub (pinned to 49183d7e8d)
Solutions
- Rebuild/redeploy the backend from a consistent source tree so oauthProviderMethods and the switch agree.
- If you are extending the backend, add a switch case for every new method constant you add to the matrix.
- Add a unit test iterating oauthProviderMethods and asserting handleOAuthLogin returns non-400-default for each advertised method.
Example fix
// before: method advertised but not implemented
const (
oauthMethodBrowser = "browser"
oauthMethodDeviceCode = "device_code"
oauthMethodToken = "token"
oauthMethodSso = "sso" // added to matrix only -> 400 unsupported login method
)
// after: implement it or do not advertise it
switch method {
case oauthMethodToken: ...
case oauthMethodDeviceCode: ...
case oauthMethodBrowser: ...
case oauthMethodSso:
// handle sso
} Defensive patterns
Strategy: validation
Validate before calling
const KNOWN_METHODS = new Set(['browser', 'device_code', 'token']);
if (!KNOWN_METHODS.has(method)) throw new Error(`unknown login method ${method}`); Type guard
function isKnownMethod(m) { return ['browser', 'device_code', 'token'].includes(m); } Prevention
- Pin clients to the documented method literals.
- Backend developers: add a switch case for every constant added to oauthProviderMethods, plus a matrix/switch consistency test.
- If this surfaces in a stock build, the binary is inconsistent — rebuild from a clean tree.
When it happens
Trigger: POST /api/oauth/login {"provider":"openai","method":"<new-method>"} where "<new-method>" was added to oauthProviderMethods in the deployed binary but the switch has no case for it. Not producible by any request against an unmodified build.
Common situations: Running a custom fork or unreleased branch that extends the login methods; stale cached build after pulling new code; a test double that injects an unsupported method.
Related errors
- provider %q does not support browser oauth
- unsupported provider %q
- unsupported login method %q for provider %q
- token is required
- missing flow id
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/4e28103f9347da58.
Report an issue: GitHub.