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

  1. Fill in the 图片上游 Base URL field in the active relay profile with a valid https:// endpoint
  2. Verify the settings file (active relay profile) actually contains upstream_base_url or a base_url the fallback can use
  3. 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

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)