{"record":{"id":"148b5c9704fd985d","repo":"router-for-me/CLIProxyAPI","slug":"no-state-parameter-received-148b5c","errorCode":null,"errorMessage":"No state parameter received","messagePattern":"No state parameter received","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/auth/codex/oauth_server.go","lineNumber":207,"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":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/codex/oauth_server.go#L189-L225","documentation":"This error is returned by the local OAuth callback HTTP server used during the Codex OAuth login flow. After the provider redirects the browser back to the callback, the handler expects both 'code' and 'state' query parameters; 'state' is the anti-CSRF token generated when the flow started. If the callback request arrives without any state parameter, the server cannot correlate the response with the original request and rejects it with HTTP 400.","triggerScenarios":"A GET request to the OAuth callback URL (e.g. /callback) that carries a 'code' query parameter but no 'state' parameter, or an empty one. Typically caused by a hand-edited or truncated redirect URL, a provider/misconfigured OAuth app that drops state, or a user manually pasting an incomplete callback URL into the browser.","commonSituations":"Starting the login flow with --oauth-callback-port, then intercepting/altering the redirect; using a custom OAuth client configuration where the authorize URL was built without the state parameter; browser extensions or security tools stripping query parameters; replaying an old bookmarked callback URL after its state expired or was never issued.","solutions":["Re-run the login flow from scratch (e.g. the oauth-login command) so a fresh state is generated and the full provider redirect is followed untouched","Check that the OAuth client/authorize configuration for Codex includes the state parameter in the authorization redirect and matches the registered redirect URI","Disable browser extensions or proxies that rewrite query parameters on localhost callback URLs","If automating the flow, ensure your script passes the entire callback URL (code AND state) through verbatim"],"exampleFix":"# before (manual/incomplete callback URL)\nhttp://127.0.0.1:1455/callback?code=abc123\n\n# after (full redirect as issued by the provider)\nhttp://127.0.0.1:1455/callback?code=abc123&state=<state-from-authorize-request>","handlingStrategy":"validation","validationCode":"// On the callback URL before the server sees it, confirm both params exist:\nconst u = new URL(callbackUrl);\nif (!u.searchParams.has('state') || !u.searchParams.has('code')) {\n  throw new Error('Incomplete OAuth callback URL: code and state are both required');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never hand-edit or truncate OAuth redirect URLs; always follow the provider's redirect chain","Automate the login flow so the browser delivers the callback untouched","Register the exact redirect URI in the OAuth app config so the provider echoes state back","Treat a missing state as a potential CSRF signal and abort the flow rather than retrying with fabricated state"],"tags":["oauth","codex","authentication","csrf"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}