BigPizzaV3/CodexPlusPlus · error · anyhow::Error
图片上游 Base URL 不能为空
Error message
图片上游 Base URL 不能为空
What it means
open_image_proxy_request requires a non-empty upstream base URL for image API requests. After resolving the effective base URL and rejecting local proxy addresses, it bails if the URL is still empty/whitespace. This prevents issuing requests with an unusable upstream endpoint.
Solutions
- Fill in the 图片上游 Base URL field in the active relay profile with a valid https:// endpoint
- Verify the settings file (active relay profile) actually contains upstream_base_url or a base_url the fallback can use
- Re-apply the relay profile after editing
Example fix
// before upstream_base_url = "" // after upstream_base_url = "https://api.openai.com"
Defensive patterns
Strategy: validation
Validate before calling
let base = if relay.upstream_base_url.trim().is_empty() { crate::relay_config::relay_profile_base_url(&relay) } else { relay.upstream_base_url.trim().to_string() };
if base.trim().is_empty() { return Err("upstream base url is empty"); } Try / catch
match open_image_edits_proxy_request(...) {
Err(e) if e.to_string().contains("Base URL 不能为空") => eprintln!("请先在当前中转配置图片上游 Base URL: {e}"),
other => other?,
} Prevention
- Always fill upstream_base_url when creating a profile
- Add a save-time check in the UI rejecting empty URLs
- Audit profiles after settings migrations for blank fields
When it happens
Trigger: Calling open_image_generations_proxy_request or open_image_edits_proxy_request when both relay.upstream_base_url is blank/whitespace and the relay_profile_base_url fallback also yields an empty string.
Common situations: Freshly created relay profile with no upstream URL configured; profile field cleared in the manager UI; settings file migrated without the upstream_base_url key.
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/0a3c99ec8696d5aa.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/protocol_proxy.rs:992
async fn open_image_proxy_request(
body: &[u8],
content_type: &str,
original_user_agent: Option<&str>,
endpoint_kind: ImageProxyEndpoint,
) -> anyhow::Result<UpstreamProxyResponse> {
let settings = SettingsStore::default().load().unwrap_or_default();
let relay = crate::relay_rotation::select_relay_for_probe(&settings)?;
let base_url = if relay.upstream_base_url.trim().is_empty() {
crate::relay_config::relay_profile_base_url(&relay)
} else {
relay.upstream_base_url.trim().to_string()
};
if is_local_protocol_proxy_base_url(&base_url) {
anyhow::bail!("图片上游 Base URL 不能指向本地协议代理");
}
if base_url.trim().is_empty() {
anyhow::bail!("图片上游 Base URL 不能为空");
}
if relay.api_key.trim().is_empty() && !relay.uses_no_auth() {
anyhow::bail!("图片上游 Key 不能为空");
}
let content_type = content_type.trim();
let content_type = if content_type.is_empty() {
match endpoint_kind {
ImageProxyEndpoint::Generations => "application/json",
ImageProxyEndpoint::Edits => {
anyhow::bail!("图片 edits 请求缺少 Content-Type");
}
}
} else {
content_type
};
let endpoint = endpoint_kind.url(&base_url);
let wire_api = endpoint_kind.wire_api();
let _ = crate::diagnostic_log::append_diagnostic_log(View on GitHub (pinned to b1ed92e5e4)