BigPizzaV3/CodexPlusPlus · error

图片上游 Key 不能为空

Error message

图片上游 Key 不能为空

What it means

open_image_proxy_request requires an upstream API key for image API requests unless the relay profile is explicitly configured with no-auth mode. It bails when api_key is empty/whitespace and uses_no_auth() is false. This ensures the upstream image API call carries credentials.

Solutions

  1. Set the 图片上游 Key (api_key) in the active relay profile
  2. If the upstream genuinely needs no key, enable the profile's no-auth option so uses_no_auth() returns true
  3. Re-apply the profile and retry the image request

Example fix

// before
api_key = ""
// after
api_key = "sk-..."
Defensive patterns

Strategy: validation

Validate before calling

if relay.api_key.trim().is_empty() && !relay.uses_no_auth() { return Err("upstream api key missing"); }

Try / catch

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

Prevention

When it happens

Trigger: Calling open_image_generations_proxy_request or open_image_edits_proxy_request with the active relay profile's api_key blank and uses_no_auth() not enabled.

Common situations: New profile created without pasting the upstream API key; key removed during profile edit; using a paid image API that requires auth while profile was copied from a no-auth local setup.

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/07cfc2a05c8a4081. Report an issue: GitHub.

Appendix: source

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

    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(
        "protocol_proxy.image_request",
        json!({
            "relayId": relay.id,

View on GitHub (pinned to b1ed92e5e4)