profile reload requires the root Include entry 报错:DSH插件启停失败怎么排查
dsh: profile reload requires the root Include entry 表示 DeepSeek Harness 在一次 profile 重载时没找到根 Include 条目——重载必须从根 Include(profile 的 cordis.yml)开始重新组合插件树,缺了它就整树组不起来、直接失败。对应动作是「先把根 Include 条目补回去,再重启实例」,而不是在报错的活实例上继续反复点火启停(来源)。
这句报错看着像配置写坏了,其实是一句「重载前置条件没满足」。有用户实跑遇到:在 CLI 的 web 实例里调用官方的 pluginManager.setBundleEnabled 想热启停一个 bundle,返回 application:"failed",附带的就是这句话;当时磁盘上的配置已经改过,而进程还活着(来源)。下面把「它是什么、怎么修、为什么会发生」三件事依次说清,最后补两条官方机制。
profile reload 报错含义:root Include entry 是什么
root Include entry 是 DeepSeek Harness 用来加载 profile 根配置的那条 loader 条目,它指向 profile 的 cordis.yml;profile 重载要从这条根 Include 开始,才能把用户补丁与各 bundle 逐层组合起来(来源)。 先把三个角色对上号:
| 名词 | 是什么 | 和这句报错的关系 |
|---|---|---|
| profile | 插件按顺序叠加的启动配置栈 | 重载的对象就是当前 profile |
| 根 Include 条目 | loader 的 cordis:include 条目,指向 cordis.yml | 「requires the root Include entry」要的就是它 |
cordis.yml | profile 根配置文件,顶层是 loader 条目数组 | 根 Include 实际加载的文件,缺或坏都会触发 |
按这个顺序认一遍:
- 它是重载的前置条件,不是数据损坏:报错原文是
dsh: profile reload requires the root include entry(用户搜索时也常打小写),说的是「重载时需要根 Include 条目」,属于前置校验失败,不是你的会话或模型配置被写坏。预期:文件多半仍在磁盘上,只是这次重载没拿到它。 - 它只在「活实例重载」这条路径上更容易出现:进程从零启动(冷启动)同样会读根 Include,但走的是 boot 路径;热重载走的是「重新组合插件树」那条路径,对根 Include 的就绪状态要求更硬。预期:重启进程后同样的配置能正常起来,这是本报错最典型的特征。
- 它和「插件没启用」不是一回事:插件没启用是条目被
disabled: true停掉,插件树照样组合;本报错是根 Include 这条地基没找到,整棵树的组合都做不下去。预期:报错时往往是「一个都不生效」,而不是「只有某一个不生效」。
记住一句话:它是一句「重载做不下去」的地基报错,不是某个插件的错。
profile reload 报错怎么修:补回根 include 条目与重启
修法主线是「先补回根 Include 条目,再重启实例」——因为活实例的插件名单在启动时就组合好了,运行期热重载对根 Include 的要求更严,重启一次最省事。 按顺序执行:
- 先确认根 Include 条目在不在。打开 profile 目录,找到根配置文件
cordis.yml(路径形如$DSH_HOME/profiles/<name>/cordis.yml)。预期:文件存在,且内容是一个顶层数组([...]);如果它是空的、或不是数组,问题就出在这里。 - 把根配置内容补回默认值。若
cordis.yml被改空或被写成非数组,按官方 config-catalog 的写法恢复成顶层条目数组即可——根配置本身是固定内容,插件不该写进这里(来源)。预期:保存后文件是合法的 YAML 顶层数组。 - 检查是不是插件把配置写进了根文件。有些插件会把组合出来的行回写进
cordis.yml;正确做法是让插件写进 patch 层(cordis.patch.yml),而不是根文件。预期:根文件保持固定内容,插件条目都落在 patch 层。 - 重启实例,而不是热重载。用
Ctrl+C停掉dsh web,再重新npx @deepseek-ai/dsh web。预期:终端重新打印监听地址,插件树从根 Include 重新组合,这句报错不再出现(来源)。 - 用 dump 确认组合结果。跑
dsh --profile web --dump-config,看你关心的插件条目是否出现在合成结果里(来源)。预期:条目在、内容也对,说明根 Include 与 patch 层都对上了。
一句提醒:别在报错的活实例上继续反复点火启停——那正是触发这句话的动作,越点越乱;改完文件重启才是正路。
profile reload 报错为什么会发生:手改 yml 与插件启停
它出现的两个高发场景是「手改 cordis.yml」和「在活实例上启停 bundle」——前者会让根 Include 指向的内容变成非法形状,后者会让重载在没有根 Include 就绪态的情况下被触发。 对照着看:
| 触发场景 | 为什么会命中 | 处理方向 |
|---|---|---|
手工编辑过 cordis.yml | 根配置被写空、写成非数组、或路径写错 | 恢复根配置内容,插件条目移回 patch 层 |
| 插件把组合行回写进根文件 | 根文件被塞进了本该在 patch 层的行 | 让插件改走 cordis.patch.yml |
| 活实例上启停 bundle | bundle 名单启动时已组合,重载缺根 Include 就绪态 | 直接重启实例,别依赖热启停 |
| 用第三方插件管理开关 | 开关调用底层启停接口,触发同一条重载路径 | 改配置后重启,或先在市场里禁用该插件 |
逐条展开:
- 手改根文件最容易踩坑:
cordis.yml是根配置,内容是固定形状;往里塞插件条目,下次重载就可能判成非法。预期:把插件条目搬到cordis.patch.yml后报错消失。 - 插件覆盖配置时要看它写在哪一层:当某个插件会替你改写配置、又改到了根文件,可以从 DSH Plugin Hub 的已安装列表里先把它禁用或卸载,再手工恢复根配置。预期:在市场里禁用后重启,根文件不再被改写。
- 启停 bundle 的路径本身就是热重载:官方
setBundleEnabled在活实例上调用会触发一次重载,而该实例的 bundle 名单在启动时就定好了,所以它更容易撞上根 Include 的前提校验(来源)。预期:改成「改配置 + 重启」后不再报这句。 - 配置分层与覆盖顺序是另一回事:哪一层覆盖哪一层、
--patch为什么优先级最高,属于配置分层的知识,和这条重载报错不同,写法见《DeepSeek Harness 插件配置怎么改:config 块与 patch 覆盖》。预期:分清「地基没找到」和「层叠写错了」两类问题。
边界:如果你遇到的是「并发启动时偶发校验失败、事后文件却完好」,那属于 cordis.yml 覆盖竞态,不是本报错——竞态排查见《DSH plugin 多进程同时启动损坏 profile》。
DSH插件 排查注意事项
- 先分清「冷启动能起、热重载报错」:这是本报错最典型的信号,别先怀疑数据损坏。
- 根文件不当草稿纸:插件条目写 patch 层,根
cordis.yml只放固定内容。 - 改完就重启:bundle 名单启动时组合,运行期热重载比冷启动更挑前置条件。
- 用 dump 验证:
--dump-config看合成结果,--dump-config-schema看能配什么。 - 插件改写配置要溯源:怀疑哪个插件动过根文件,先在市场里禁用它,再恢复根配置。
DSH插件 profile 重载的官方机制
理解官方两句话,排查会更有方向:profile 根配置由 loader 的 include 条目加载,插件树重载要能拿回这条根 Include;同时 bundle 名单是启动时组合的。 两点说明:
- 根 Include 是加载入口:官方文档把「每个
config:块均可由cordis.yml条目设置」作为总原则,而这条根配置正是通过 loader 的 include 条目加载的(来源)。预期:理解了「include 是入口」,就明白为什么它缺了整树就组合不了。 - 热重载与冷启动有分界:patch 变更走 profile 重载;而 bundle 名单在启动时组合,所以依赖运行期启停往往不如重启可靠(来源)。预期:把「改文件 + 重启」当默认手法,能绕开大部分本类报错。
与其一边改 cordis.yml 一边担心把根 Include 条目改没,不如用 DSH Plugin Hub 的图形界面启停与卸载插件——它把写法交给标准命令,你只负责点确认。

常见问题
这句表示 DeepSeek Harness 在一次 profile 重载时没能找到根 Include 条目(用户搜索时也常写成小写的 root include entry),重载要从它开始重新组合插件树,缺了就直接失败。 它通常出现在用插件管理开关启停 bundle、而不是重启进程的时候。
DeepSeek Harness 的 bundle 名单在启动时就组合好了,运行期再调 setBundleEnabled 会触发一次 profile 重载,而活实例此刻拿不到根 Include 条目,于是返回 failed。 最稳的修法是改完直接重启实例,别依赖热启停。
在 DeepSeek Harness 里根 Include 条目必须存在且能解析,报这个错并不一定说明 cordis.yml 被删了。 profile 根配置就是 cordis.yml,由 loader 的 cordis:include 条目加载;检查它是不是顶层数组、路径对不对、有没有被插件覆盖,再决定补回还是重建 profile。
在 DeepSeek Harness 里遇到这个错,先把根 Include 条目补回去——恢复根配置的默认内容,或按官方 config-catalog 重写插件条目,改坏太多就用默认 profile 重建。 启用插件优先走 DSH Plugin Hub 的启停开关或标准 add/remove 命令,别让插件直接改根配置。
这个报错与 cordis.yml 覆盖竞态、配置分层不生效不是同一回事:profile reload requires the root Include entry 说的是 DeepSeek Harness 重载缺根 Include 条目,覆盖竞态讲的是并发启动撞上零长度窗口,配置分层讲的是多层 patch 谁覆盖谁。 三者都涉及 cordis.yml,但触发条件与修法各不相同。
相关术语
- root Include entry
- root Include entry 是 DeepSeek Harness 用来加载 profile 根配置的 loader 条目,指向 profile 的 cordis.yml;profile 重载必须从它开始,缺了就无法重新组合插件树。— DeepSeek Harness 官方文档 - 插件配置目录
- profile reload
- profile reload 是 DeepSeek Harness 在不重启进程的前提下重新读取 profile 配置、重新组合插件树的过程,由 patch 变更或插件启停触发。— dsh CLI 官方 README
- cordis.yml
- cordis.yml 是 DeepSeek Harness 每个 profile 的根配置文件,内容是顶层 loader 条目数组,被 loader 的 cordis:include 条目当作根 Include 加载。— DeepSeek Harness 官方文档 - 插件配置目录
- setBundleEnabled
- setBundleEnabled 是 DeepSeek Harness 提供的启停 bundle 接口;在活实例上调用它会触发一次 profile 重载,重载缺少根 Include 条目时返回 application:failed。— 社区插件 dsh-backroom 实测记录