{"record":{"id":"525b1cbfa9adb20c","repo":"sipeed/picoclaw","slug":"no-authorization-code-received","errorCode":null,"errorMessage":"No authorization code received","messagePattern":"No authorization code received","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/auth/oauth.go","lineNumber":204,"sourceCode":"\nfunc oauthCallbackRedirectURI(port int) string {\n\treturn fmt.Sprintf(\"http://localhost:%d/auth/callback\", port)\n}\n\nfunc oauthCallbackHandler(state string, resultCh chan<- callbackResult) http.Handler {\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/auth/callback\", func(w http.ResponseWriter, r *http.Request) {\n\t\tif r.URL.Query().Get(\"state\") != state {\n\t\t\tresultCh <- callbackResult{err: fmt.Errorf(\"state mismatch\")}\n\t\t\thttp.Error(w, \"State mismatch\", http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\n\t\tcode := r.URL.Query().Get(\"code\")\n\t\tif code == \"\" {\n\t\t\terrMsg := r.URL.Query().Get(\"error\")\n\t\t\tresultCh <- callbackResult{err: fmt.Errorf(\"no code received: %s\", errMsg)}\n\t\t\thttp.Error(w, \"No authorization code received\", http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\n\t\tw.Header().Set(\"Content-Type\", \"text/html\")\n\t\tfmt.Fprint(w, \"<html><body><h2>Authentication successful!</h2><p>You can close this window.</p></body></html>\")\n\t\tresultCh <- callbackResult{code: code}\n\t})\n\treturn mux\n}\n\nfunc listenOAuthCallback(port int) (net.Listener, int, error) {\n\tlistener, err := net.Listen(\"tcp\", fmt.Sprintf(\"127.0.0.1:%d\", port))\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\ttcpAddr, ok := listener.Addr().(*net.TCPAddr)\n\tif !ok {","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/auth/oauth.go#L186-L222","documentation":"In the OAuth callback handler, after the state check passes, a callback that carries no code parameter is rejected; the error message embeds the error query parameter (which may itself be empty). Per the OAuth2 spec the provider redirects with error=... (plus error_description) when authorization failed, so this signals the provider-side or user-side failure leg of the flow rather than a transport problem.","triggerScenarios":"(1) User clicked Deny / cancelled consent → error=access_denied; (2) misconfigured client_id, requested scope, or redirect_uri → error=invalid_request / unauthorized_client / invalid_scope; (3) provider outage returning an error redirect; (4) an IdP that responds to the callback without either parameter (nonstandard).","commonSituations":"Scopes requested that the app registration does not have consent for; redirect URI registered in the provider portal not matching http://localhost:<port>/auth/callback; app in verification/pending state; user's admin policies blocking consent.","solutions":["Read the embedded error value in the message — access_denied means user denial, invalid_* points at client registration","Verify client_id/secret and the exact redirect URI (scheme, port, path) registered with the provider","Trim requested scopes to those the app registration actually grants, then retry login","Retry the full flow from a fresh authorize URL"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"token, err := auth.Login(ctx)\nif err != nil {\n    msg := err.Error()\n    switch {\n    case strings.Contains(msg, \"access_denied\"):\n        return errors.New(\"user denied consent — restart login and approve the requested scopes\")\n    case strings.Contains(msg, \"invalid_scope\"), strings.Contains(msg, \"unauthorized_client\"):\n        return errors.New(\"provider rejected the request — verify client_id, scopes and redirect URI registration\")\n    }\n    return err\n}","preventionTips":["Register the exact redirect URI (http://localhost:<port>/auth/callback) in the provider console before the first login","Request only scopes the app registration grants; trim scopes when invalid_scope appears","Treat an embedded error value as authoritative provider feedback and fix the registration, not the code"],"tags":["oauth","auth","http"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}