BigPizzaV3/CodexPlusPlus · error
中转 Key 不能为空
Error message
中转 Key 不能为空
What it means
在 apply_relay_config_to_home_with_protocol 写入 Codex home 之前,对 bearer_token 做 trim 后非空校验。为空时立即 bail,不会产生任何 config.toml / auth.json 写入或备份。这是把「中转 Base URL + Key」一键投影为 Codex 配置的入口函数(apply_relay_config_to_home 的带协议参数变体)。
Source
Thrown at crates/codex-plus-core/src/relay_config.rs:280
RelayProtocol::Responses,
crate::protocol_proxy::DEFAULT_PROTOCOL_PROXY_PORT,
)
}
pub fn apply_relay_config_to_home_with_protocol(
home: &Path,
base_url: &str,
bearer_token: &str,
protocol: RelayProtocol,
proxy_port: u16,
) -> anyhow::Result<RelayApplyResult> {
let base_url = base_url.trim();
if base_url.is_empty() {
anyhow::bail!("中转 Base URL 不能为空");
}
let bearer_token = bearer_token.trim();
if bearer_token.is_empty() {
anyhow::bail!("中转 Key 不能为空");
}
let codex_base_url = codex_base_url_for_protocol(base_url, protocol, proxy_port);
let updated = upsert_model_provider_config("", &codex_base_url, bearer_token, true)?;
let auth_contents = serde_json::to_string_pretty(&json!({
"OPENAI_API_KEY": bearer_token
}))?;
let backup_path =
write_codex_live_atomic(home, Some(&updated), Some(auth_contents.as_bytes()), false)?;
let status = relay_config_status_from_home(home);
Ok(RelayApplyResult {
config_path: status.config_path,
backup_path,
configured: status.configured,
})
}
pub fn apply_pure_api_config_to_home(
home: &Path,View on GitHub (pinned to 1f431ae49b)
Solutions
- 在调用前 trim 并检查 bearer_token 非空,为空时在 UI 层拦截
- 检查 RelayProfile 的 api_key / auth_contents 字段是否为空(relay_profile_api_key 会从其中解析)
- 若确实不需要写入 key,改用直接写 config.toml 的 apply_relay_config_file_to_home 接口
- 从环境变量取 key 时确认变量已设置且值不是纯空白
Example fix
// before
let result = apply_relay_config_to_home_with_protocol(&home, &base_url, "", protocol, port)?;
// after
let token = bearer_token.trim();
if token.is_empty() {
return Err(anyhow::anyhow!("中转 Key 不能为空"));
}
let result = apply_relay_config_to_home_with_protocol(&home, base_url, token, protocol, port)?; Defensive patterns
Strategy: validation
Validate before calling
let token = bearer_token.trim();
if token.is_empty() {
return Err(anyhow::anyhow!("中转 Key 不能为空"));
}
apply_relay_config_to_home_with_protocol(&home, base_url, token, protocol, proxy_port)?; Try / catch
match apply_relay_config_to_home_with_protocol(&home, base_url, token, protocol, port) {
Ok(result) => { /* ... */ }
Err(err) if err.to_string().contains("中转 Key 不能为空") => {
// 定位到 Key 输入框提示用户,不重试
}
Err(err) => return Err(err),
} Prevention
- UI 表单提交前 trim 并非空校验 Key 字段,为空禁用提交按钮
- 从 RelayProfile 取值时统一走 relay_profile_api_key 再校验
- 环境变量读取后立即检查空值,不要把空串静默传下去
When it happens
Trigger: 调用 apply_relay_config_to_home_with_protocol(home, base_url, bearer_token, protocol, proxy_port) 时 bearer_token.trim() 为空字符串(空串或纯空白字符)。注意 base_url 会先被校验,所以本错误只在 base_url 非空而 key 为空时出现。
Common situations: 前端表单 Key 输入框留空白就点「应用」;RelayProfile 的 api_key 字段为空(relay_profile_api_key 解析后为空);从环境变量读取 key 但变量未设置;误以为可以只配 base_url 不配 key( Responses 协议中转仍需要 key 写入 auth.json 的 OPENAI_API_KEY)。
Related errors
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@1f431ae49b (2026-08-16).
Data as JSON: /api/errors/8f4b908dcdb94e08.
Report an issue: GitHub.