jlcodes99/cockpit-tools · error
默认 OAuth client 配置无效
Error message
默认 OAuth client 配置无效
What it means
get_auth_url in crates/cockpit-core/src/modules/oauth.rs:77 builds the Google OAuth authorization URL and calls oauth_client_config(None).expect("默认 OAuth client 配置无效"). The Err path comes from resolve_oauth_client_key, which only fails when a preferred client key that is not the default is supplied. Since get_auth_url passes None, the resolver always returns the default key, so this panic is a defensive guard and is effectively unreachable at runtime unless the code is changed to forward a user-specified client key.
Source
Thrown at crates/cockpit-core/src/modules/oauth.rs:77
Some(key) if key.is_empty() => Ok(DEFAULT_OAUTH_CLIENT_KEY.to_string()),
Some(key) => Err(format!(
"未知 OAuth client: {},当前版本仅支持 {}",
key, DEFAULT_OAUTH_CLIENT_KEY
)),
None => Ok(DEFAULT_OAUTH_CLIENT_KEY.to_string()),
}
}
fn oauth_client_config(
preferred: Option<&str>,
) -> Result<(&'static str, &'static str, String), String> {
let key = resolve_oauth_client_key(preferred)?;
Ok((CLIENT_ID, CLIENT_SECRET, key))
}
/// 生成 OAuth 授权 URL
pub fn get_auth_url(redirect_uri: &str, state: Option<&str>) -> String {
let (client_id, _, _) = oauth_client_config(None).expect("默认 OAuth client 配置无效");
let scopes = vec![
"openid",
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/cclog",
"https://www.googleapis.com/auth/experimentsandconfigs",
]
.join(" ");
let mut params = vec![
("client_id", client_id),
("redirect_uri", redirect_uri),
("response_type", "code"),
("scope", &scopes),
("access_type", "offline"),
("prompt", "consent"),
];View on GitHub (pinned to 1ed8b77992)
Solutions
- Keep calling get_auth_url with no preferred client (the only currently supported key) so the resolver returns the default.
- If adding a custom client, extend resolve_oauth_client_key to accept the new key instead of passing an unknown one.
- Change get_auth_url to return Result<String, String> and propagate the error from oauth_client_config instead of using .expect.
Example fix
// before
let (client_id, _, _) = oauth_client_config(None).expect("默认 OAuth client 配置无效");
// after
let (client_id, _, _) = oauth_client_config(None)?; // fn get_auth_url(...) -> Result<String, String> Defensive patterns
Strategy: validation
Validate before calling
// Callers of get_auth_url today cannot trigger this (None is always Ok), but if you pass a preferred key:
const supported = ["default"];
if (preferred && !supported.includes(preferred.trim().toLowerCase())) {
throw new Error(`未知 OAuth client: ${preferred}`);
} Type guard
function isSupportedOAuthClient(key: string): boolean {
return key.trim().toLowerCase() === 'default';
} Try / catch
// Rust callers of a Result-returning variant:
let url = get_auth_url_checked(redirect_uri, state)
.unwrap_or_else(|e| { log::error!("oauth config: {e}"); String::new() }); Prevention
- Never pass an unknown preferred client key; use only the supported default.
- Prefer returning Result over .expect when adding configurable client support.
- Add a unit test asserting oauth_client_config(None) is Ok.
When it happens
Trigger: Only when the call chain is modified so that get_auth_url forwards a preferred client identifier that is non-empty and does not equal DEFAULT_OAUTH_CLIENT_KEY (case-insensitively), causing resolve_oauth_client_key to return Err and .expect to panic.
Common situations: A developer adds multi-client support or a configurable client key and passes an unsupported/renamed key (e.g. a provider preset renamed or removed in a new version) into get_auth_url; end users never hit this directly.
Related errors
- 无效的 Auth URL
- 解析语言文件失败 {}: {}
- expected launch path must exist
- [Windsurf OAuth] 回调服务恢复失败: login_id={}, error={}
- Claude login start 响应缺少关键字段
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/cbe462233b6a2106.
Report an issue: GitHub.