Replies: 2 comments
|
机制分析完全成立——补一条给已经中招用户的即时恢复动作,因为你报告里的机制恰好也给出了它: 改名(rename)不销毁内容—— 两个配套建议:
你这个「导入成功性与文件改名顺序」的发现值得进 #6520 那份未修复清单——它是和迁移拒绝同一家族的「升级流程自己制造数据风险」问题,而且修复成本极低(先导入后改名,或失败时回滚改名)。 |
0 replies
|
感谢补充,完全正确——rename 保留的是原文件,「永久丢失」应为「永久不重试」,我们实际就是从 同意收录 #6520 的未修复清单,修复建议维持「先导入后改名:任一 section 失败保留原文件、下次启动重试」。 |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Version
0.1.7-alpha.1 (dsh-v0.1.7-alpha.1)
Summary
The one-time
settings.yamlimport introduced in 0.1.7 renames the file tosettings.yaml.importedbefore attempting to import any section. If the running composition cannot accept one or more sections on that boot (e.g. the first boot after upgrade has a plugin entry that fails to activate or stays pending), every rejected section is only logged as a warning, the original file is already gone, and the import never retries — because the file no longer exists on the next boot.Net effect: a transient first-boot problem turns into permanent, silent loss of the entire settings.yaml (model providers, default model, permission presets, plugin settings), with no recovery path other than manual reconstruction.
Reproduction
settings.yaml(e.g. LLM provider definitions, agent default model, permission presets).dsh web. The loader settles (with the failed entry),importLegacyDocument()runs, the file is renamed immediately, and eachupdate()for the settings sections throws ("No configurable plugin entry ...") because the composition is not fully addressable.settings.yamlis already renamed. Restarting does not retry — the file is gone.Observed on 0.1.7-alpha.1 / Linux /
dsh web. The behavior matches the code comment in@deepseek-ai/dsh-settings("The document is renamed before the first write, so a partial import never repeats") — but that ordering converts a partial failure into an unrecoverable full loss.Root cause
importLegacyDocument()performsrename(path, imported)before the per-section import loop. The rename is unconditional; import success is not.Expected behavior / suggested fix
Import first, rename last: keep the original
settings.yamlin place when any section fails (rejected sections stay ignored on disk), and retry the import on the next boot — only drop/rename the file once every section has been accepted. That single ordering change makes the one-time import self-healing instead of destructive.(Optionally also surface a visible notice in the web UI when sections are rejected, instead of server-log-only warnings.)
中文版(附)
标题
settings.yaml 一次性导入:先改名后导入,导入失败即静默丢失全部设置
摘要
0.1.7 的 settings.yaml 一次性导入在执行任何 section 导入之前就把文件改名为
settings.yaml.imported。若该次启动组合树中有插件条目激活失败或 pending,各 section 的导入会被拒绝(仅服务端日志 warn),而原文件已被收走,下次启动也不会重试——文件已不存在。后果:一次瞬时的首启动异常 → 整个 settings.yaml 永久静默丢失(模型 provider、默认模型、权限预设、插件设置),除手工重建外无恢复路径。
复现
dsh web:loader 结束后importLegacyDocument()立即改名,随后各 sectionupdate()因组合不可寻址抛出 "No configurable plugin entry";根因
importLegacyDocument()的rename(path, imported)在按 section 导入循环之前无条件执行,改名与导入成败无关。期望行为 / 修复建议
先导入、后改名:任何一个 section 失败时保留原 settings.yaml(被拒 section 留在原文件中),下次启动重试导入;全部 section 接受后才收走文件。仅这一处顺序调整即可让一次性导入从「破坏性」变为「自愈性」。
(可选:section 被拒时在 Web UI 给出可见提示,而非仅服务端日志。)
All reactions