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
- Set the 上游 Base URL (base_url) in the active relay profile to a valid https:// endpoint
- Inspect the settings file to confirm base_url is present on the active profile
- 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
- Require base_url at profile creation time
- Run a pre-flight validate_upstream check in callers
- Detect blank fields after settings migrations
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)