Repository navigation
Replies: 6 comments 1 reply
|
Your write-up is precise enough that the mechanism can be settled from the source, and it changes one part of your inference in a way that matters: the error is not swallowed — it is emitted, into a sink nobody can read. Three facts, each with its line. 1. The failure is real, and in-process it is logged. 2. Startup only fails for core entry ids; a third-party failure is a warning on stderr. 3. That is why your search returned 0. The persistent report under So the honest summary of your incident: the plugin did fail, the harness did name the reason, and the only durable record was a stderr line the desktop shell discards. The market showing it as installed and enabled is a separate, also-expected fact: the market reflects the profile row, not the activation result. You can confirm this without reinstalling the removed plugin. Mount two throwaway plugins that each register a tool with the same name and launch the CLI from a terminal ( On the plugin-form option — the state is readable without any core change. The loader exposes its entries ( On your four asks, specifically:
|
|
| mount spelling | Config on the plugin object |
result |
|---|---|---|
ctx.plugin(moduleNamespace) |
absent (the namespace exposes no Config) |
mounts |
ctx.plugin(moduleNamespace.default) |
plain object | throws |
loader entry (unwrapExports returns .default) |
plain object | throws |
| any spelling | standard-schema | mounts and validates |
The asymmetry is the trap: ctx.plugin(import * as mod) works while the identical module fails when a profile mounts it, because unwrapExports returns moduleNamespace.default ?? moduleNamespace and the loader registers that object. A harness that mounts the namespace, therefore, cannot see the defect that the deployment hits. I hit it the moment the doctor was mounted as an entry.
The fix is one line — drop the Config export and normalize in code, or declare a schema — and it is what this package does, with the reasoning in the source. I have not filed anything upstream about it: the behaviour reads as intended (a plain object is not a schema), and what is missing is not a change but a signal — which is this package's whole subject.
What it was measured against
node scripts/probe-lines.mjs copies the package into a scratch tree per line, pins the whole line (17 packages, read back from disk to prove the pins applied), installs with --legacy-peer-deps, builds and runs the suite:
@deepseek-ai/dsh-tools0.1.7-rc.2,0.2.0-rc.2,0.2.1-alpha.2— all PASS@deepseek-ai/cordis4.0.4,4.0.5-alpha.1— both covered by those three trees
The suite mounts a real context, the real loader, the real SystemPrompt and ToolRuntime, and real fixture modules on disk; the incident is reproduced rather than simulated (two fixtures claim one tool name, the second throws, its fiber unloads whole), and a control arm mounts everything except the doctor, so "the report names the failure" is never confounded with "the failure happened at all". npm run test:inject mutates each distinction in turn: 25 arms, 25 caught, 0 silent.
|
Follow-up: the same mount failure was in ten more of my published plugins — fixed at The doctor announced above reports plugins that are mounted but never activate. Sweeping my published plugins against the shape behind that failure turned up ten more, all mine, all one line:
before the first line of Why the suites stayed green is the part worth keeping. Every test in those packages imports the module namespace ( The rule I'd take from it: a plugin's |
|
English summary. Thank you for the mechanism walkthrough — it matches our report line by line. We have corrected our original claim: the failure is not "logged nowhere"; it goes to 感谢 @argszero 的机制说明,逐条对上了我们这边观察到的现象。按你的回帖,我们把原帖里不准确的地方更正如下(原帖保留以便对照): 更正 1|不是"无任何日志",而是"写进了没有 sink 的 logger" 更正 2|CLI 从终端启动时,stderr 上其实有一行 我们此前只在桌面端复现,所以从来没看到这一行——这也是"零命中"的来源之一。 更正 3|桌面端把 stderr 收进了内存 仍然成立的部分:一个插件只要在 下一步(本机验证):我们会在 Windows 11(26100)+ DSH Desktop 0.2.0-rc.2 上,按你给的方式做一次复现——两个只注册同一个工具名的一次性插件,挂在独立 profile 里从终端启动——然后把 stderr 原文与 |
Verified on Windows — the doctor works, and here is the whole failure from the outsideI ran an isolated reproduction of the mechanism described in this thread instead of only reasoning about it. Nothing here touched my real profile: a fresh Install gate. The tarball I audited matches the registry: Arm 1 — two plugins registering the same tool name. Terminal: The first registrant stays active, the second plugin is unloaded whole, and the doctor's own line names entry plus error and points at the report file. That is exactly the silent-disappearance symptom: the marketplace still lists the plugin as installed and enabled. Arm 2 — control. With only one probe mounted there is no warning line and no report file at all. The doctor does not cry wolf. Arm 3 — is the failed fiber's registration released? Not synchronously with the throw. A second probe in the same include batch still collided with the name the throwing probe had registered microseconds earlier; a probe that waited 2.5 s and then registered the same name succeeded. So the unload does release the effects, but a collision can cascade inside one startup batch. Arm 4 — import-level failures are classified separately. An entry whose module never loads is reported as One desktop-path note, not a plugin bug. On this machine The launcher rejects the Thanks again — the sweep-then-file behaviour is the part the harness itself does not do, and it survives the two cases that matter: a body throw with a stack, and a module that never loaded. |
|
Follow-up: three more "the user cannot see it" failure classes, with on-machine evidence Context: this is a Windows 11 desktop that (a) runs the desktop app, (b) had its 1. Storage layer — an external cleaner removed the storage a live session was using, and the harness neither noticed nor reported it
What we would ask the harness to do (small and concrete): verify, at startup and periodically, that the directories it owns still exist ( 2. Agent loop — a tool call whose arguments are not valid JSON kills the whole turnWe located the exact code in the shipped
Three occurrences, all on the same tool (
So the provider is not at fault and the harness is honest — the model emitted invalid JSON — but the reaction is the problem: the turn dies with an error banner, there is no retry, the model gets no chance to fix its own malformed call, and the raw malformed arguments are not persisted to 3. Why this belongs in this threadAll three are the same complaint this discussion is about: the harness fails in ways the user can neither see nor act on. The doctor plugin is a good start — we installed it through the in-app installer and reproduced the name-collision failure live ( (Private-data note: this comment contains no credentials, no file contents, and no personal paths beyond 中文摘要:本次追加的是三条“用户看不见”的失败类证据——① 外部清理器把正在运行会话的 |
Uh oh!
There was an error while loading. Please reload this page.
环境
DeepSeek Harness.exe文件版本),profile=desktop@a9i5k4/dsh-auto-memory3.2.14、dsh-continual-evolve0.15.4、以及一个自研 MCP 记忆插件现象(都是实测,不是推理)
三个记忆类插件同时启用后重启 DSH,其中一个插件(
@a9i5k4/dsh-auto-memory)看起来已安装、已启用,但实际完全没有生效,而且任何地方都没有一条错误:lib/index.js:1135的staticHead: '[记忆系统 — 固定纪律]…'与:8190 renderMemoryStatic()提供)在重启后的系统提示里完全消失。memory_log, memory_recall, memory_read, memory_rules, memory_note, memory_user, memory_status, memory_external, memory_trace, memory_reflect, memory_expand, memory_procedure, memory_procedure_list, memory_consolidate, memory_maintain%DSH_HOME%\dsh-auto-memory-diagnose.log在重启后没有新增任何一行(最后一行停在重启前:turn-stopping fired: turn=17 hasAgent=true),说明它的apply阶段根本没有走到写日志的那一步。package.json的dependencies里有它,profile 的cordis.patch.yml里有它的行。用户没有任何办法知道它其实是死的。复现命令与结果
代码依据(只读检索安装包内
@deepseek-ai/dsh-tools)同类"重名即抛"的守卫也存在于系统提示层:
@deepseek-ai/dsh-system-prompt/lib/index.js:190-192(section / context / variable 同名都会抛… is already registered)。我们的推断(明确是推断)
同时启用的两个记忆插件提供同名工具(我们这边两边都有
memory_read)。按上面的守卫,后注册的一方会抛错;插件apply期间抛错 → 它之前注册的所有 effect 被回滚 → 该插件"整体静默失效",而错误只在宿主内部被吞掉/未落盘。诚实说明:其中一个插件已在故障当天被我们卸载(
%DSH_HOME%\profiles\desktop\.dsh-market\log.ndjson有uninstall … exit=0记录),所以我们现在无法复现、也拿不到原始抛错堆栈。这也是我写这条帖子的原因之一:错误一旦丢失就再也找不回来。相关既有讨论(本条不重复它们)
发帖前我检索了既有讨论,机制层面已经有帖子覆盖,我在这里明确引用,避免重复报告:
…dsh-tools/lib/index.js:2634(NamedEntries.duplicateError)←:29(insert)←:2886(layers.effect.label)←dsh-scope/lib/index.js:206,并指出 factory-default profile 下也会出现;其回复还提到切换 preset 后静默少工具(会话只有 13 个工具,缺subagent/list_subagent_models)。rpc.handle注册静默失败):同属"注册失败对用户不可见"这一类。本条补充的是第三方插件之间冲突时的用户侧观测结果:日志 0 命中、市场仍显示已启用、插件自身诊断日志停止增长,并且一次冲突会把该插件的全部工具 + 系统提示注入段一起抹掉——用户没有任何可见线索。这与 #8201 的"单条 [E] 日志"不同:我们这里连一条日志都没有。
诉求(按优先级)
failed to register: tool "memory_read" is already registered …,并写入%DSH_HOME%\logs下的持久日志(现在搜索结果为 0)。dsh doctor plugins之类的命令。agent.ctx注册,没有说明跨插件同层重名时的官方建议(命名空间前缀?声明式依赖?)。我不是这两个插件的作者,以上全部是终端用户侧的只读取证。如果维护者需要,我可以重装那两个插件做一次复现并把原始抛错栈贴回来。
All reactions