BigPizzaV3/CodexPlusPlus · error

中转 Key 不能为空

Error message

中转 Key 不能为空

What it means

Thrown by `apply_relay_config_to_home_with_session_provider` in relay_config.rs when `bearer_token` is empty after trimming. The token becomes the API key written into config.toml/auth for the relay provider; without it codex could not authenticate. The check runs after base_url validation and before the session-provider/protocol compatibility check.

Solutions

  1. Provide the relay bearer token / API key as the bearer_token argument.
  2. Resolve the key from a secret store or env var and assert it is non-empty before applying.
  3. Gate the apply action in the UI on a non-empty key field.

Example fix

// before
let token = std::env::var("RELAY_KEY").unwrap_or_default();
apply_relay_config_to_home_with_protocol(home, url, &token, ...).await?;
// after
let token = std::env::var("RELAY_KEY").context("RELAY_KEY not set")?;
apply_relay_config_to_home_with_protocol(home, url, &token, ...).await?;
Defensive patterns

Strategy: validation

Validate before calling

let token = bearer_token.trim();
anyhow::ensure!(!token.is_empty(), "中转 Key 不能为空");

Type guard

fn has_token(t: &str) -> bool { !t.trim().is_empty() }

Try / catch

match apply_relay_config_to_home_with_protocol(home, url, key, proto, port, sp).await {
    Ok(r) => Ok(r),
    Err(e) if e.to_string().contains("中转 Key 不能为空") => Err(anyhow::anyhow!("请先在中转站设置中填写 API Key")),
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling `apply_relay_config_to_home_with_protocol` with a valid base_url but `bearer_token = ""` or whitespace; bails at relay_config.rs:405.

Common situations: Profile stored without a key (user chose 'fill later'); env var holding the token unset at apply time; token cleared by an edit in the manager UI but apply still invoked.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19). Data as JSON: /api/errors/8f4b908dcdb94e08. Report an issue: GitHub.

Appendix: source

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

        RelaySessionProvider::Custom,
    )
}

pub fn apply_relay_config_to_home_with_session_provider(
    home: &Path,
    base_url: &str,
    bearer_token: &str,
    protocol: RelayProtocol,
    proxy_port: u16,
    session_provider: RelaySessionProvider,
) -> 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 不能为空");
    }
    if session_provider == RelaySessionProvider::Openai && protocol != RelayProtocol::Responses {
        anyhow::bail!("OpenAI 会话身份仅支持 Responses API");
    }
    let codex_base_url = codex_base_url_for_protocol(base_url, protocol, proxy_port);
    let updated = upsert_model_provider_config_with_session_provider(
        "",
        &codex_base_url,
        bearer_token,
        true,
        session_provider,
    )?;
    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()))?;
    let status = relay_config_status_from_home(home);

View on GitHub (pinned to b1ed92e5e4)