BigPizzaV3/CodexPlusPlus · warning · anyhow::Error

供应商配置总开关已关闭,未写入 config.toml / auth.json。

Error message

供应商配置总开关已关闭,未写入 config.toml / auth.json。

What it means

switch_relay_profile_in_home 是切换供应商的总入口。第一步就检查 BackendSettings.relay_profiles_enabled(供应商配置总开关):为 false 时直接 bail,不读快照、不写 settings.json、不碰 config.toml / auth.json。这是一种「拒绝执行」守卫而非故障——系统状态完全未被改动。

Source

Thrown at crates/codex-plus-core/src/relay_switch.rs:26

};
use crate::settings::{BackendSettings, RelayMode, SettingsStore};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RelaySwitchResult {
    pub settings: BackendSettings,
    pub configured: bool,
    pub backup_path: Option<String>,
}

pub fn switch_relay_profile_in_home(
    store: &SettingsStore,
    home: &Path,
    next_settings: BackendSettings,
    previous_active_relay_id: &str,
) -> anyhow::Result<RelaySwitchResult> {
    let mut selected_settings = next_settings;
    if !selected_settings.relay_profiles_enabled {
        anyhow::bail!("供应商配置总开关已关闭,未写入 config.toml / auth.json。");
    }
    crate::codex_app_state::capture_app_state_snapshot_nonfatal(home, "relay_switch.before");

    let original_settings = store.load().unwrap_or_default();
    let live_snapshot = LiveFilesSnapshot::capture(home).context("读取当前 Codex 实时配置失败")?;
    if !previous_active_relay_id.trim().is_empty()
        && previous_active_relay_id != selected_settings.active_relay_id
    {
        backfill_profile_before_switch(home, &mut selected_settings, previous_active_relay_id)?;
    }

    store
        .save(&selected_settings)
        .context("保存供应商设置失败")?;
    let selected_settings = store.load().context("读取供应商设置失败")?;

    match apply_selected_relay_profile(home, &selected_settings) {
        Ok(result) => {

View on GitHub (pinned to 1f431ae49b)

Solutions

  1. 在设置里重新打开「供应商配置总开关」后重试
  2. 调用方在调用前检查 next_settings.relay_profiles_enabled
  3. UI 在开关关闭时禁用切换按钮,避免无效调用

Example fix

// before
switch_relay_profile_in_home(&store, &home, next, &prev_id)?;

// after
if !next.relay_profiles_enabled {
    return Err(anyhow::anyhow!("供应商配置总开关已关闭,未写入 config.toml / auth.json。"));
}
switch_relay_profile_in_home(&store, &home, next, &prev_id)?;
Defensive patterns

Strategy: validation

Validate before calling

if !next_settings.relay_profiles_enabled {
    return Err(anyhow::anyhow!(
        "供应商配置总开关已关闭,未写入 config.toml / auth.json。"
    ));
}
switch_relay_profile_in_home(&store, &home, next_settings, previous_active_relay_id)?;

Try / catch

match switch_relay_profile_in_home(&store, &home, next, &prev_id) {
    Ok(result) => { /* ... */ }
    Err(err) if err.to_string().contains("总开关已关闭") => {
        // 引导用户打开开关;不要自动改 settings 强行切换
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: 在 relay_profiles_enabled == false 的 settings 上调用 switch_relay_profile_in_home(包括 UI 点切换、定时任务、导入后自动切换等任何路径)。

Common situations: 用户关掉了「供应商配置」总开关后,残留的切换调用(前端按钮未同步禁用);settings.json 被外部工具改写把开关置 false;自动化脚本未检查开关状态。

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@1f431ae49b (2026-08-16). Data as JSON: /api/errors/ff4d4d10503cda61. Report an issue: GitHub.