{"record":{"id":"b7cad3a46f3aba0a","repo":"BigPizzaV3/CodexPlusPlus","slug":"model-providers-transport-provider-id","errorCode":null,"errorMessage":"活动协议代理需要现有 model_providers.{transport_provider_id} 配置","messagePattern":"活动协议代理需要现有 model_providers\\.(.+?) 配置","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/relay_config.rs","lineNumber":323,"sourceCode":"        .with_context(|| format!(\"读取 {} 失败\", config_path.display()))?;\n    let mut doc = parse_toml_document(&existing)?;\n    let managed = managed_openai_base_url();\n    let mut changed = false;\n\n    if transport_uses_proxy {\n        let session_provider_id = active_session_provider_id(&doc);\n        let transport_provider_id = if session_provider_id == \"openai\" {\n            RELAY_PROVIDER.to_string()\n        } else {\n            active_or_default_provider_id(&doc)\n        };\n        let provider = doc\n            .get_mut(\"model_providers\")\n            .and_then(Item::as_table_mut)\n            .and_then(|providers| providers.get_mut(&transport_provider_id))\n            .and_then(Item::as_table_mut)\n            .ok_or_else(|| {\n                anyhow::anyhow!(\"活动协议代理需要现有 model_providers.{transport_provider_id} 配置\")\n            })?;\n        let current = provider\n            .get(\"base_url\")\n            .and_then(Item::as_str)\n            .map(str::trim);\n        if current != Some(managed.as_str()) {\n            provider[\"base_url\"] = toml_edit::value(managed.as_str());\n            changed = true;\n        }\n    }\n\n    if openai_identity_uses_proxy {\n        let before = doc\n            .get(OPENAI_BASE_URL_KEY)\n            .and_then(Item::as_str)\n            .map(str::trim)\n            .map(ToString::to_string);\n        update_remote_control_openai_base_url(&mut doc, true);","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/relay_config.rs#L305-L341","documentation":"ensure_active_protocol_proxy_config_in_home configures the active-protocol proxy by rewriting base_url inside the model_providers.<transport_provider_id> table of config.toml. This error is thrown when that provider entry does not exist (model_providers table missing, or the provider id absent, or it is not a table). The function intentionally does NOT create the provider; it only patches an existing one.","triggerScenarios":"Calling the apply flow (apply_relay_profile_to_home_with_switch_rules family) with a profile whose transport_provider_id has no corresponding [model_providers.<id>] table in config.toml — e.g. the provider was deleted, renamed, or the profile references a provider never written by CodexPlusPlus.","commonSituations":"User manually removed a provider section from config.toml, switched profiles and the target provider id no longer matches, or upgraded the fork and the provider naming scheme changed while old configs remained.","solutions":["Add (or restore) the `[model_providers.<transport_provider_id>]` table in config.toml with a base_url, matching the id reported in the error.","Check the active RelayProfile's transport_provider_id and correct it to an existing provider id in config.toml.","Re-apply the relay profile so CodexPlusPlus writes the provider table before enabling the active-protocol proxy.","Back up and rebuild config.toml from the profile settings to resync provider ids."],"exampleFix":"// before (config.toml) — missing provider\n# no [model_providers.deepseek] section\n// after (config.toml)\n[model_providers.deepseek]\nname = \"DeepSeek\"\nbase_url = \"https://api.deepseek.com/v1\"","handlingStrategy":"validation","validationCode":"let doc = std::fs::read_to_string(\"~/.codex/config.toml\")?.parse::<toml_edit::DocumentMut>()?;\nlet ok = doc.get(\"model_providers\")\n    .and_then(|p| p.get(transport_provider_id))\n    .map(|i| i.is_table())\n    .unwrap_or(false);\nif !ok { /* create the provider table first */ }","typeGuard":"fn provider_exists(doc: &toml_edit::DocumentMut, id: &str) -> bool {\n    doc.get(\"model_providers\")\n        .and_then(|p| p.get(id))\n        .map(|i| i.is_table())\n        .unwrap_or(false)\n}","tryCatchPattern":"if let Err(e) = ensure_active_protocol_proxy_config_in_home(...) {\n    if e.to_string().contains(\"需要现有 model_providers\") {\n        // write the missing [model_providers.<id>] table, then retry\n    }\n}","preventionTips":["Always create the provider table via the library before enabling the active-protocol proxy","Keep transport_provider_id in the profile in sync with provider ids actually present in config.toml","Audit config.toml after profile switches to ensure providers were not dropped","Never hand-delete a [model_providers.*] section that the active profile references"],"tags":["toml","config","missing-provider"],"backgroundTag":"missing-required-config-field","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}