BigPizzaV3/CodexPlusPlus · critical · anyhow::Error

切换供应商失败:{error};同时回滚配置失败:settings.json={},Codex 实时文件={}

Error message

切换供应商失败:{error};同时回滚配置失败:settings.json={},Codex 实时文件={}

What it means

switch_relay_profile_in_home 的失败恢复路径:apply_selected_relay_profile 出错后,会尝试两项回滚——store.save(original_settings) 恢复 settings.json、live_snapshot.restore(home) 恢复 config.toml/auth.json。任一回滚也失败时,抛出这条复合错误,把「原始切换错误 + settings.json 回滚结果 + 实时文件回滚结果」三段拼在一起。出现它意味着系统处于未知的中间状态,必须人工核对文件。

Source

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

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

    match apply_selected_relay_profile(home, &selected_settings) {
        Ok(result) => {
            crate::codex_app_state::sync_app_state_after_provider_switch_nonfatal(
                home,
                "relay_switch.after",
            );
            Ok(result)
        }
        Err(error) => {
            let settings_restore_error = store.save(&original_settings).err();
            let live_restore_error = live_snapshot.restore(home).err();
            if settings_restore_error.is_some() || live_restore_error.is_some() {
                anyhow::bail!(
                    "切换供应商失败:{error};同时回滚配置失败:settings.json={},Codex 实时文件={}",
                    settings_restore_error
                        .map(|error| error.to_string())
                        .unwrap_or_else(|| "ok".to_string()),
                    live_restore_error
                        .map(|error| error.to_string())
                        .unwrap_or_else(|| "ok".to_string())
                );
            }
            Err(error)
        }
    }
}

#[derive(Debug, Clone)]
struct LiveFilesSnapshot {
    config: Option<Vec<u8>>,
    auth: Option<Vec<u8>>,

View on GitHub (pinned to 1f431ae49b)

Solutions

  1. 先读消息第一段「切换供应商失败:{error}」确定切换本身失败的原因并修复
  2. 看消息尾部 settings.json= 与 Codex 实时文件= 哪个不是 ok,针对该文件检查权限/占用/磁盘空间
  3. 关闭占用 config.toml / auth.json 的进程(codex、同步工具)后重试切换
  4. 若文件已不一致,从 backup_path 指向的备份手工恢复 config.toml,再手动核对 settings.json
Defensive patterns

Strategy: try-catch

Try / catch

match switch_relay_profile_in_home(&store, &home, next, &prev_id) {
    Ok(result) => Ok(result),
    Err(err) if err.to_string().contains("同时回滚配置失败") => {
        // 复合失败:解析三段(切换错误 / settings.json / 实时文件),
        // 停止一切自动重试;提示用户关闭占用进程、检查权限与磁盘,
        // 并引导从 backup_path 备份手工恢复 config.toml
        report_inconsistent_state(&err);
        Err(err)
    }
    Err(err) => Err(err),
}

Prevention

When it happens

Trigger: 切换供应商中途失败(例如 profile 校验失败、TOML 解析失败),且随后 settings.json 写回或 config.toml/auth.json 恢复也失败(磁盘满、目录只读、文件被其他进程占用、权限被回收)。

Common situations: home 目录权限被改动;codex 进程正持有 auth.json;磁盘空间耗尽导致原子写失败;杀毒/同步软件(OneDrive 等)锁定配置文件。

Related errors


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