Kuberwastaken/claurst · error
No query string in callback
Error message
No query string in callback
What it means
The OAuth callback parser expects the browser's request line to be `GET /path?query HTTP/1.1` and locates the authorization code by finding the `?` that starts the query string. If the request path contains no `?`, there is no code/state to extract and the flow bails with this error. It usually means the browser hit the callback URL without the OAuth parameters.
Solutions
- Restart the OAuth flow and complete authorization in one pass — do not manually re-enter or refresh the callback URL.
- Check the authorization provider's redirect: if an error occurred, the flow should present it — retry login.
- Verify the auth URL was opened as generated (with its query parameters) rather than retyped.
- If a proxy or extension is stripping query params, disable it for localhost.
Example fix
// before (manual navigation) // http://127.0.0.1:1455/auth/callback -> No query string in callback // after: use the full URL as produced by the flow // http://127.0.0.1:1455/auth/callback?code=...&state=...
Defensive patterns
Strategy: validation
Validate before calling
// Only open the exact auth URL printed by the flow (it contains ?code=...&state=...) // Verify in browser devtools that the final redirect URL retains its query string.
Try / catch
match run_oauth_flow(&mut app).await {
Err(e) if e.to_string().contains("No query string in callback") => {
eprintln!("Callback arrived without OAuth parameters; restart the login and use the printed URL as-is");
}
other => other?,
} Prevention
- Never retype, trim, or refresh the callback URL — always follow the generated auth link end-to-end.
- Disable browser extensions that rewrite or strip URL parameters for localhost.
- Don't point health checks or probes at the OAuth callback port.
When it happens
Trigger: `wait_for_callback` received a request line whose path has no query string: the user navigated to `http://127.0.0.1:<port>/` directly, the auth server redirected without parameters (error redirect handled elsewhere or stripped), or a health-check/probe hit the port.
Common situations: User manually refreshes or re-opens the callback URL after the query was dropped; browser extension strips URL parameters; authorization failed upstream and the redirect carried no `?code=`; port scanner or monitoring tool connecting to the local listener.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Missing code or state in OAuth callback
- Failed to parse OAuth callback URL
- Bridge register: server returned
- Token exchange failed
- OAuth state mismatch — possible CSRF attack
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/bbcb02a7a684a8dd.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/cli/src/codex_oauth_flow.rs:134
std::time::Duration::from_secs(300), // 5 minute timeout
listener.accept(),
)
.await
.map_err(|_| anyhow!("OAuth callback timeout (5 minutes)"))?
.map_err(|e| anyhow!("Failed to accept connection: {}", e))?;
let mut reader = BufReader::new(&mut socket);
let mut request_line = String::new();
reader.read_line(&mut request_line).await?;
// Parse "GET /auth/callback?code=...&state=... HTTP/1.1"
let parts: Vec<&str> = request_line.split_whitespace().collect();
if parts.len() < 2 {
bail!("Invalid HTTP request");
}
let path = parts[1];
let query_start = path.find('?').ok_or_else(|| anyhow!("No query string in callback"))?;
let query = &path[query_start + 1..];
let mut code = String::new();
let mut state = String::new();
let mut error = String::new();
for param in query.split('&') {
let kv: Vec<&str> = param.splitn(2, '=').collect();
if kv.len() == 2 {
match kv[0] {
"code" => code = urlencoding::decode(kv[1])?.to_string(),
"state" => state = urlencoding::decode(kv[1])?.to_string(),
"error" => error = urlencoding::decode(kv[1])?.to_string(),
"error_description" => error = urlencoding::decode(kv[1])?.to_string(),
_ => {}
}
}
}
View on GitHub (pinned to b0637c97ec)