lbjlaq/Antigravity-Manager · critical
Failed to build OAuth URL
Error message
Failed to build OAuth URL
What it means
get_auth_url unwraps get_auth_url_with_client with expect, panicking with 'Failed to build OAuth URL' when URL construction fails (e.g. no active OAuth client configured or the client's endpoints are missing/invalid). It is a fatal invariant: the function's signature promises a String.
Solutions
- Ensure an OAuth client is configured and set as active before calling get_auth_url
- Validate client config fields (valid URLs, non-empty client_id) at load time
- Refactor get_auth_url to return Result<String, Error> and propagate instead of expect/panic
Example fix
// before
pub fn get_auth_url(redirect_uri: &str, state: &str) -> String {
get_auth_url_with_client(redirect_uri, state, None)
.map(|(url, _)| url)
.expect("Failed to build OAuth URL")
}
// after
pub fn get_auth_url(redirect_uri: &str, state: &str) -> Result<String, OAuthError> {
get_auth_url_with_client(redirect_uri, state, None)
.map(|(url, _)| url)
.map_err(|e| OAuthError::UrlBuild(e.to_string()))
} Defensive patterns
Strategy: validation
Validate before calling
if let Err(e) = validate_client_config(&config) { return Err(format!("OAuth client misconfigured: {}", e)); } Try / catch
let url = get_auth_url_with_client(uri, state, None).map(|(u, _)| u).map_err(|e| eprintln!("oauth url build failed: {e}"))?; Prevention
- Validate OAuth client fields (URLs parse, ids non-empty) at config load
- Never use expect in library-level code; return Result
- Add a startup check that an active client exists before OAuth routes are exposed
When it happens
Trigger: Calling get_auth_url when no active OAuth client exists, when client_cfg fields (auth_url/client_id) are empty or malformed so Url::parse fails, or any Err from get_auth_url_with_client.
Common situations: App first-run without OAuth client config; config file edited and an endpoint URL broken; get_auth_url called before client initialization completes.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- Failed to parse model_specs.json
- accounts.add.oauth.error_no_url
- JSONC normalization preserves UTF-8
- OAuth state mismatch
AI-assisted analysis of lbjlaq/Antigravity-Manager@90a2b6b207 (2026-09-19).
Data as JSON: /api/errors/417fe1bdad9412d9.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/modules/oauth.rs:366
("redirect_uri", redirect_uri),
("response_type", "code"),
("scope", &scopes),
("access_type", "offline"),
("prompt", "consent"),
("include_granted_scopes", "true"),
("state", state),
];
let url = url::Url::parse_with_params(AUTH_URL, ¶ms)
.map_err(|e| format!("Invalid Auth URL: {}", e))?;
Ok((url.to_string(), client.key))
}
/// Generate OAuth authorization URL using current active client.
pub fn get_auth_url(redirect_uri: &str, state: &str) -> String {
get_auth_url_with_client(redirect_uri, state, None)
.map(|(url, _)| url)
.expect("Failed to build OAuth URL")
}
async fn exchange_code_once(
code: &str,
redirect_uri: &str,
client_cfg: &OAuthClientConfig,
) -> Result<TokenResponse, (Option<reqwest::StatusCode>, String)> {
// [PHASE 2] 对于登录行为,尚未有 account_id,使用全局池阶梯逻辑
let client = if let Some(pool) = crate::proxy::proxy_pool::get_global_proxy_pool() {
pool.get_effective_standard_client(None, 60).await
} else {
crate::utils::http::get_long_standard_client()
};
let params = [
("client_id", client_cfg.client_id.as_str()),
("client_secret", client_cfg.client_secret.as_str()),
("code", code),View on GitHub (pinned to 90a2b6b207)