BigPizzaV3/CodexPlusPlus · error

API Key 不能为空

Error message

API Key 不能为空

What it means

test_relay_profile 在 base_url 校验通过后校验 API Key:relay_profile_api_key(profile) trim 后为空则 bail,不发起网络请求。key 之后会作为 bearer_auth 头发送。

Source

Thrown at crates/codex-plus-core/src/relay_config.rs:534

        config_path: status.config_path,
        backup_path,
        configured: status.configured,
    })
}

pub async fn test_relay_profile(
    profile: &RelayProfile,
    model: &str,
) -> anyhow::Result<RelayProfileTestResult> {
    let base_url = relay_profile_base_url(profile);
    let base_url = base_url.trim().trim_end_matches('/');
    if base_url.is_empty() {
        anyhow::bail!("Base URL 不能为空");
    }
    let api_key = relay_profile_api_key(profile);
    let api_key = api_key.trim();
    if api_key.is_empty() {
        anyhow::bail!("API Key 不能为空");
    }

    let client = crate::http_client::proxied_client("CodexPlusPlus/RelayTest")?;
    let endpoint = match profile.protocol {
        RelayProtocol::Responses => format!("{base_url}/responses"),
        RelayProtocol::ChatCompletions => format!("{base_url}/chat/completions"),
    };
    let test_model = model.trim();
    if test_model.is_empty() {
        anyhow::bail!("测试模型不能为空");
    }

    let payload = relay_profile_test_payload(profile.protocol, test_model);
    let response = client
        .post(&endpoint)
        .bearer_auth(api_key)
        .header(reqwest::header::CONTENT_TYPE, "application/json")
        .json(&payload)

View on GitHub (pinned to 1f431ae49b)

Solutions

  1. 为 profile 填写 API Key 后再测试
  2. 确认 auth_contents JSON 中的键名为 OPENAI_API_KEY(relay_profile_api_key 识别的格式)
  3. 调用前本地做同样的 trim 校验,给用户表单级提示

Example fix

// before
let r = test_relay_profile(&profile_no_key, "gpt-5").await?;

// after
if relay_profile_api_key(&profile).trim().is_empty() {
    return Err(anyhow::anyhow!("API Key 不能为空"));
}
let r = test_relay_profile(&profile, "gpt-5").await?;
Defensive patterns

Strategy: validation

Validate before calling

if relay_profile_api_key(profile).trim().is_empty() {
    return Err(anyhow::anyhow!("API Key 不能为空"));
}
test_relay_profile(profile, model).await?;

Try / catch

match test_relay_profile(&profile, &model).await {
    Ok(result) => { /* 展示连通性结果 */ }
    Err(err) if err.to_string().contains("API Key 不能为空") => { /* 提示补 Key */ }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: 调用 test_relay_profile 时 profile 的 api_key 解析结果为空(RelayProfile 的 api_key / auth_contents 相关字段均无可用值)。

Common situations: 新建 profile 未填 Key 就点「测试连接」;key 存在 auth_contents JSON 里但字段名不是 OPENAI_API_KEY;配置迁移后 key 丢失。

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@1f431ae49b (2026-08-16). Data as JSON: /api/errors/4df38db34d186a9e. Report an issue: GitHub.