BigPizzaV3/CodexPlusPlus · error

测试模型不能为空

Error message

测试模型不能为空

What it means

test_relay_profile 的第三个守卫:测试用的 model 参数 trim 后为空则 bail。该 model 会填入请求 payload(relay_profile_test_payload 按协议生成最小请求体),为空说明调用方没传有效模型名。前两个守卫(base_url、API Key)已通过才会走到这里。

Source

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

    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)
        .send()
        .await?;
    let http_status = response.status().as_u16();

    // 如果 404 且 base_url 末尾没有 /v1,尝试自动补 /v1 后再发一次。
    // 许多上游(中转站、自建代理)暴露的路径以 /v1/ 开头,
    // 用户容易遗漏这个前缀,导致 /responses 或 /chat/completions 404。
    if http_status == 404 && !base_url.ends_with("/v1") {
        let v1_url = format!("{base_url}/v1");
        let v1_endpoint = match profile.protocol {

View on GitHub (pinned to 1f431ae49b)

Solutions

  1. 传入非空模型名(如 profile 的默认模型或用户选中的模型)
  2. 调用前检查 model.trim() 非空,空时用 profile 默认模型回填
  3. UI 层在未选模型时禁用测试按钮

Example fix

// before
let r = test_relay_profile(&profile, "  ").await?;

// after
let model = model.trim();
let model = if model.is_empty() { relay_profile_model(&profile) } else { model.to_string() };
anyhow::ensure!(!model.trim().is_empty(), "测试模型不能为空");
let r = test_relay_profile(&profile, &model).await?;
Defensive patterns

Strategy: validation

Validate before calling

let model = model.trim();
let model = if model.is_empty() { relay_profile_model(profile) } else { model };
anyhow::ensure!(!model.trim().is_empty(), "测试模型不能为空");
test_relay_profile(profile, &model).await?;

Try / catch

if let Err(err) = test_relay_profile(&profile, &model).await {
    if err.to_string().contains("测试模型不能为空") {
        // 模型下拉未选中:给默认值后让用户重试
    } else { return Err(err); }
}

Prevention

When it happens

Trigger: 调用 test_relay_profile(profile, model) 时 model 是空串或纯空白,例如 UI 上模型选择框未选中、settings 的默认测试模型(default_relay_test_model 相关字段)被清空。

Common situations: 测试按钮没绑定模型选择值;profile.model_list 为空导致模型下拉无默认项;把模型名误当可选项省略。

Related errors


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