{"record":{"id":"df95ee03172323aa","repo":"router-for-me/CLIProxyAPI","slug":"no-state-parameter-received","errorCode":null,"errorMessage":"No state parameter received","messagePattern":"No state parameter received","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/auth/claude/oauth_server.go","lineNumber":210,"sourceCode":"\t}\n\n\tif code == \"\" {\n\t\tlog.Error(\"No authorization code received\")\n\t\tresult := &OAuthResult{\n\t\t\tError: \"no_code\",\n\t\t}\n\t\ts.sendResult(result)\n\t\thttp.Error(w, \"No authorization code received\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tif state == \"\" {\n\t\tlog.Error(\"No state parameter received\")\n\t\tresult := &OAuthResult{\n\t\t\tError: \"no_state\",\n\t\t}\n\t\ts.sendResult(result)\n\t\thttp.Error(w, \"No state parameter received\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\t// Send successful result\n\tresult := &OAuthResult{\n\t\tCode:  code,\n\t\tState: state,\n\t}\n\ts.sendResult(result)\n\n\t// Redirect to success page\n\thttp.Redirect(w, r, \"/success\", http.StatusFound)\n}\n\n// handleSuccess handles the success page endpoint.\n// It serves a user-friendly HTML page indicating that authentication was successful.\n//\n// Parameters:","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/claude/oauth_server.go#L192-L228","documentation":"The Claude OAuth callback had a code but no state query parameter, so the anti-CSRF check cannot proceed. The handler sends OAuthResult{Error: \"no_state\"} and returns HTTP 400 \"No state parameter received\".","triggerScenarios":"GET /callback?code=abc with state missing, emptied, or renamed (?st=, ?session=) by manual editing or a misconfigured IdP redirect template.","commonSituations":"Provider redirect-uri templates that drop unknown params; hand-crafted callback URLs during testing; auth flows through intermediaries that whitelist only certain query keys.","solutions":["Re-run the login flow so the browser delivers both code and state as issued","Verify the provider's redirect configuration passes through the full query string","When testing manually, include both parameters: /callback?code=abc&state=<the state your flow generated>"],"exampleFix":"# before\ncurl \"http://127.0.0.1:1455/auth/callback?code=abc\"\n# 400 No state parameter received\n\n# after\ncurl \"http://127.0.0.1:1455/auth/callback?code=abc&state=xyz\"","handlingStrategy":"validation","validationCode":"q := u.Query()\nif q.Get(\"state\") == \"\" { return errors.New(\"callback URL missing state parameter\") }","typeGuard":"func callbackHasState(u *url.URL) bool { return u.Query().Get(\"state\") != \"\" }","tryCatchPattern":"result, err := server.WaitForCode(ctx)\nif err == nil && result.Error == \"no_state\" { /* restart login; ensure IdP passes through the full query string */ }","preventionTips":["Don't hand-edit callback URLs","Verify the IdP redirect template forwards all query parameters"],"tags":["claude","oauth","state","csrf"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}