
环境Mac-mini ~ % atomcode --versionatomcode 5.0.3Mac-mini ~ % node -vv22.21.0报错[错误: provider “” not found]复现步骤复现前置条件核心config.toml中default_provider为空、[providers.*]为空。代码依据Config::default()里default_provider: String::new()config/mod.rs:467首次登录若 codingplan claim 未成功持久化commands.rs:6762的should_persist_config()为 false配置就保持这个空状态。方式 A走真实首次登录时序# 1. 隔离全新配置目录不污染现有环境exportATOMCODE_HOME$(mktemp-d/tmp/atomcode-repro.XXXX)echoATOMCODE_HOME$ATOMCODE_HOME# 2. 启动 TUI 并首次登录atomcode# → 执行 /login 完成 OAuth只保证写 auth.toml# → 如果 claim/models 环节未成功无额度/网络波动config.toml 不会被写入# 3. 检查配置状态关键诊断步骤确认根因命中cat$ATOMCODE_HOME/config.toml2/dev/null||echoconfig.toml 不存在grep-Edefault_provider|^\[providers$ATOMCODE_HOME/config.toml\||echo→ 命中根因无 default_provider / 无 providers# 4. 执行 /webui在打开的页面里发送一条消息或切换模型下拉框# → 聊天区出现 [错误: provider not found]方式 B稳定复现不依赖 claim 时序最可控# 1. 全新配置目录exportATOMCODE_HOME$(mktemp-d/tmp/atomcode-repro.XXXX)cd$ATOMCODE_HOME# 2. 手动构造已登录但无可用 provider的环境catconfig.tomlEOF default_workdir /tmp EOF# 把已登录的 auth.toml 复制进来或正常登录一次后拷贝cp~/.atomcode/auth.toml$ATOMCODE_HOME/auth.toml# 3. 启动 TUI → /webui → 页面操作 → 复现同上后端行为验证最直接即使不操作页面POST /live/provider对空 provider 的拒绝是确定性的live_api.rs:1525-1529curl-s-XPOST http://127.0.0.1:13457/live/provider\-HContent-Type: application/json\-d{provider:}# 期望返回{ok:false,error:provider \\ not found}注意/webui模式开启 token 鉴权HttpOnly Cookie直接 curl 会 401可从浏览器 DevTools 里复制带 Cookie 的 fetch 来验证或直接观察页面内报错即可。关键提示复现窗口首次登录后 → config.toml 尚未写入default_provider之前。一旦run_login_flow成功持久化claim 成功或重启后配置就绪/live/provider校验通过问题消失——这正是你重启后正常的原因。稳定复现要点保证 config 里没有default_provider和[providers.*]登录态auth.toml存在即可其余操作在 webui 页面内完成。复现步骤已给出完毕上面两种方式 后端验证 诊断命令。两个任务项均已完成。如果你按步骤跑完把结果比如config.toml的 grep 输出、页面报错截图或 curl 返回发给我我可以进一步确认是否命中同一根因或者直接帮你落地之前说的修复补丁后端/live/provider空 provider 兜底回退。根因首次登录后config.toml里没有可用的默认 providerwebui 同步链路把空字符串当作 provider 发给了后端被校验拒绝。证据链1. 空 provider 的来源crates/atomcode-config/src/config/mod.rs:467— 全新Config的默认值default_provider:String::new(),// 空字符串providers:HashMap::new(),// 没有任何 provider首次登录前config.toml不存在或没有default_provider读到的就是空串。2. 登录流程只在特定条件下写配置crates/atomcode-tuix/src/event_loop/commands.rs:6762—/loginrun_login_flow只有report.should_persist_config()codingplan claim/models 全部成功时才把配置持久化ifreport.should_persist_config(){matchctx.config_store.update(|latest|{...merge_successful_config...})即仅仅 OAuth 登录成功写入auth.toml并不保证config.toml有default_provider。首次登录如果 claim/模型拉取未完成配置仍是空默认值。3./webui把空 provider 带进同步链路commands.rs:2062/webui命令先调用attach_live_runtime它用ctx.config.default_provider空串注册绑定 runtimecommands.rs:562,567。随后打开浏览器加载 SPA前端与 live hub 同步时携带该空 provider。4. 后端拒绝空 provider —— 错误的确切出处crates/atomcode-daemon/src/live_api.rs:1525-1529POST /live/provider前端postLiveProvider调用if!config.selection_exists(req.provider){// 不在任何 selection 中returnJson(serde_json::json!({ok:false,error:format!(provider {:?} not found,req.provider),// → provider not found}));}{:?}对空字符串格式化正好输出与报错完全一致其它几处provider ... not found都是Some()或路径参数格式不匹配。前端把该error经pushCommandNotice渲染为[错误: provider not found]i18nchat.error [错误: {msg}]。5. 为什么重启后就好了重启时ctx.config从磁盘重新加载。若首次登录时 codingplan 已成功持久化或第二次进入时启动流程补齐了默认 providerdefault_provider变为非空/webui绑定与/live/provider校验通过。本质是内存/磁盘配置状态与登录进度的时序差而非随机故障。修复建议按优先级后端兜底live_api.rs:1525req.provider为空时回退到live_current_provider()已绑定 runtime 的 provider或config.default_provider不要直接 400。前端防呆Chat.tsx:1392/ModelSelector.tsxprovider 为空串时不发postLiveProvider()同步或同步前先用getConfig()的默认值填充。登录流程补强commands.rs:6762OAuth 成功后即使 claim 未完成也提示/引导用户配置或领取默认 provider避免留下已登录但无可用模型的空窗状态。