{"record":{"id":"deffc367da3eb5d0","repo":"BigPizzaV3/CodexPlusPlus","slug":"openai-responses-api","errorCode":null,"errorMessage":"OpenAI 会话身份仅支持 Responses API","messagePattern":"OpenAI 会话身份仅支持 Responses API","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/relay_config.rs","lineNumber":335,"sourceCode":"\npub fn apply_relay_config_to_home_with_session_provider(\n    home: &Path,\n    base_url: &str,\n    bearer_token: &str,\n    protocol: RelayProtocol,\n    proxy_port: u16,\n    session_provider: RelaySessionProvider,\n) -> anyhow::Result<RelayApplyResult> {\n    let base_url = base_url.trim();\n    if base_url.is_empty() {\n        anyhow::bail!(\"中转 Base URL 不能为空\");\n    }\n    let bearer_token = bearer_token.trim();\n    if bearer_token.is_empty() {\n        anyhow::bail!(\"中转 Key 不能为空\");\n    }\n    if session_provider == RelaySessionProvider::Openai && protocol != RelayProtocol::Responses {\n        anyhow::bail!(\"OpenAI 会话身份仅支持 Responses API\");\n    }\n    let codex_base_url = codex_base_url_for_protocol(base_url, protocol, proxy_port);\n    let updated = upsert_model_provider_config_with_session_provider(\n        \"\",\n        &codex_base_url,\n        bearer_token,\n        true,\n        session_provider,\n    )?;\n    let auth_contents = serde_json::to_string_pretty(&json!({\n        \"OPENAI_API_KEY\": bearer_token\n    }))?;\n    let backup_path =\n        write_codex_live_atomic(home, Some(&updated), Some(auth_contents.as_bytes()))?;\n    let status = relay_config_status_from_home(home);\n    Ok(RelayApplyResult {\n        config_path: status.config_path,\n        backup_path,","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/relay_config.rs#L317-L353","documentation":"apply_relay_config_to_home_with_session_provider (crates/codex-plus-core/src/relay_config.rs:335) enforces that the OpenAI session identity (RelaySessionProvider::Openai, ChatGPT-style login auth) is only combined with the Responses wire protocol. Codex OpenAI-session auth works only against the Responses API, so a chat-protocol config would break at runtime; this guard fails at apply time instead.","triggerScenarios":"Calling apply_relay_config_to_home_with_session_provider with session_provider = RelaySessionProvider::Openai and protocol = RelayProtocol::ChatCompletions. apply_relay_config_to_home_with_protocol always passes Custom, so this comes from the session-provider-aware entry point used by official-login flows.","commonSituations":"A user logs in with an OpenAI account, then switches the profile wire protocol to chat to reach a chat-only aggregator, and the UI forwards the Openai session provider together with the chat protocol.","solutions":["Keep protocol = Responses whenever the session provider is Openai","Switch to RelaySessionProvider::Custom with an API key if the upstream only speaks chat completions","In the UI, disable the chat protocol option (or auto-reset the session provider to Custom) while OpenAI login is active"],"exampleFix":"// before\napply_relay_config_to_home_with_session_provider(&home, url, &token, RelayProtocol::ChatCompletions, port, RelaySessionProvider::Openai)?;\n\n// after\napply_relay_config_to_home_with_session_provider(&home, url, &token, RelayProtocol::Responses, port, RelaySessionProvider::Openai)?;","handlingStrategy":"validation","validationCode":"fn session_protocol_combo_ok(provider: RelaySessionProvider, protocol: RelayProtocol) -> bool {\n    provider != RelaySessionProvider::Openai || protocol == RelayProtocol::Responses\n}\n\nif !session_protocol_combo_ok(provider, protocol) {\n    anyhow::bail!(\"OpenAI session identity requires Responses; use a Custom provider for chat\");\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = apply_relay_config_to_home_with_session_provider(&home, url, token, protocol, port, provider) {\n    if e.to_string().contains(\"OpenAI\") {\n        // invalid combo: pick Responses + Openai, or chat + Custom; do not retry unchanged\n    }\n}","preventionTips":["Encode the invariant in the UI: OpenAI session login forces wire protocol Responses","When the user picks chat protocol, auto-switch the session provider to Custom and ask for an API key","Keep a unit test asserting the (Openai, ChatCompletions) combination stays rejected"],"tags":["relay-config","session-provider","openai-auth","responses-api","rust"],"backgroundTag":"unsupported-protocol-combination","analyzedSha":"f2074595a281bc057525c748175c8eb9805b0673","analyzedAt":"2026-08-23T12:52:24.489Z","contentChangedAt":"2026-08-23T12:52:24.489Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}