Hmbown/CodeWhale · warning
OAuth callback path was not
Error message
OAuth callback path was not {} What it means
After method validation, the callback's request target path must equal the provider's configured `callback_path`. This throw means a request reached the loopback listener whose path is not the registered OAuth redirect path, so it cannot be the expected provider callback.
Solutions
- Use the complete redirect URL exactly as issued (including path and query)
- Ensure `callback_path` in provider params matches the redirect_uri registered with the provider
- Ignore/whitelist benign requests like /favicon.ico from touching the listener path check
- Restart the flow if the redirect URL was edited
Example fix
// before (edited URL) http://127.0.0.1:8765/?code=abc // after (exact callback path preserved) http://127.0.0.1:8765/oauth/callback?code=abc
Defensive patterns
Strategy: validation
Validate before calling
let path = target.split('?').next().unwrap_or(target);
assert_eq!(path, expected_callback_path, "unexpected callback path: {path}"); Type guard
fn target_matches_path(target: &str, expected: &str) -> bool {
target.split('?').next().unwrap_or(target) == expected
} Prevention
- Copy the redirect URL from the browser verbatim, never retype it
- Keep `callback_path` consistent between the auth URL and the listener config
- Return 404 for unknown paths on the listener and keep serving
When it happens
Trigger: `query_from_target` sees a target whose path (before '?') differs from `params.callback_path` — e.g. `/` from a browser hitting the root, `/favicon.ico`, or a callback path changed in provider params after the auth URL was built.
Common situations: User truncates the redirect URL in the address bar; a browser prefetches /favicon.ico on the port; provider redirect URI configured inconsistently between the auth request and the listener.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- The Codewhale service returned an unsafe verification URL
- agy OAuth token JSON carries no access token member
- agy OAuth token member
- atomically replacing xAI OAuth credentials
- bearer credentials are not an API key
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/1fd688b36d32fb05.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/oauth.rs:1261
}
}
fn parse_http_request_target(request_line: &str) -> Result<String> {
let mut parts = request_line.split_whitespace();
let method = parts.next().unwrap_or_default();
anyhow::ensure!(
method.eq_ignore_ascii_case("GET"),
"OAuth callback must be GET"
);
let target = parts
.next()
.context("OAuth callback missing request target")?;
Ok(target.to_string())
}
fn query_from_target<'a>(params: &OAuthProviderParams, target: &'a str) -> Result<&'a str> {
let path = target.split('?').next().unwrap_or(target);
anyhow::ensure!(
path == params.callback_path,
"OAuth callback path was not {}",
params.callback_path
);
Ok(target.split_once('?').map(|(_, q)| q).unwrap_or(""))
}
/// Bind the loopback callback on both IP stacks for the first free port.
///
/// The redirect URI has to say `localhost` — that is what is registered with
/// the authorization server, and redirect matching is exact — but `localhost`
/// resolves to `::1` before `127.0.0.1` on IPv6-first hosts. Binding only
/// IPv4 left the browser connecting to a closed port, which browsers paper
/// over with Happy Eyeballs fallback: a working sign-in becomes a slow one,
/// and a broken one wherever that fallback is disabled. Binding both is the
/// fix that keeps the registered redirect URI intact.
///
/// A host with only one stack available binds only that one and still works.View on GitHub (pinned to 433685b202)