BigPizzaV3/CodexPlusPlus · error

上游 Base URL 不能为空

Error message

上游 Base URL 不能为空

What it means

validate_upstream is the shared pre-flight check for proxied upstream requests: it requires relay.base_url to be non-empty before any request is forwarded. An empty URL means there is no upstream to send to, so it bails with this message. Called before building/issuing the reqwest request.

Solutions

  1. Set the 上游 Base URL (base_url) in the active relay profile to a valid https:// endpoint
  2. Inspect the settings file to confirm base_url is present on the active profile
  3. Re-apply the relay profile after editing

Example fix

// before
base_url = ""
// after
base_url = "https://api.openai.com"
Defensive patterns

Strategy: validation

Validate before calling

if relay.base_url.trim().is_empty() { return Err("upstream base url is empty"); }

Try / catch

match send_proxied_request(...) {
    Err(e) if e.to_string().contains("上游 Base URL 不能为空") => eprintln!("请在当前中转填写上游 Base URL: {e}"),
    other => other?,
}

Prevention

When it happens

Trigger: Any proxy request path that calls validate_upstream while the active relay profile's base_url is empty or whitespace after trim.

Common situations: Freshly created profile without an upstream URL; base_url cleared in the manager UI; hand-edited settings file missing base_url for the active profile.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at crates/codex-plus-core/src/protocol_proxy.rs:1219

    relay: &crate::settings::RelayProfile,
    is_stream: bool,
    upstream_body: &Value,
) -> reqwest::RequestBuilder {
    let mut builder = client
        .post(endpoint)
        .header(reqwest::header::CONTENT_TYPE, "application/json");
    builder = with_relay_auth(builder, relay);
    if is_stream {
        builder = builder
            .header(reqwest::header::ACCEPT, "text/event-stream")
            .header(reqwest::header::CACHE_CONTROL, "no-cache");
    }
    builder.json(upstream_body)
}

fn validate_upstream(relay: &crate::settings::RelayProfile) -> anyhow::Result<()> {
    if relay.base_url.trim().is_empty() {
        anyhow::bail!("上游 Base URL 不能为空");
    }
    if relay.api_key.trim().is_empty() && !relay.uses_no_auth() {
        anyhow::bail!("上游 Key 不能为空");
    }
    Ok(())
}

fn with_relay_auth(
    request: reqwest::RequestBuilder,
    relay: &crate::settings::RelayProfile,
) -> reqwest::RequestBuilder {
    if relay.uses_no_auth() {
        request
    } else {
        request.bearer_auth(relay.api_key.trim())
    }
}

View on GitHub (pinned to b1ed92e5e4)