[bug] 实验性 Playwright MCP 启动失败会导致所有会话创建失败(failOnStartupError: true + reconnect: false),并残留孤儿浏览器进程 #7865
Replies: 4 comments
你的因果链在代码里成立——而且那条
|
|
感谢确认,两个端点我在 0.1.7-alpha.1 的已发布构建产物里都对上了(mcp-client 的抛出点、browser-use-runtime 的开关点)。
按你列的方向补齐证据:故障当天原始日志、A/B 工具清单对比、failOnStartupError true → false 的行为差异。最后附代码/依赖核对记录,以及一条结论:升级到 rc.2 不会改变这个行为。
========================================
【0】结论摘要
========================================
1) 因果链成立,我同意"这是故障隔离问题"的定性。
2) 升级到 0.1.7-rc.2 不会改变这个行为:这条路径的代码在 alpha.1 与 rc.2 之间逐字节相同,master 上仍是 failOnStartupError: true。所以"升级后是否还连坐"可以不占用一次升级就回答。
3) 你提示的 tests/host-runtime-duplication.spec.ts(#4573)方向上是对的,而且该前置条件在我机器上确实成立;但请把它当"最可能的候选"而不是已证实结论——它在我这台机器上不是稳定复现的(见【6】)。
4) 一个具体建议:当前错误只暴露通用文案,底层 cause 被吞掉了。把 outcome.error 的 cause 带进 gateway/internal 的 message 或 Host 日志,会大幅缩短定位时间——我这次始终拿不到连接失败的最底层原因,只能停在"必然以同一文案失败"这一层。
========================================
【1】环境
========================================
- dsh CLI 0.1.7-alpha.1(staging + 目录交换方式安装,不是 npm i -g),Node v24.18.0,Windows
- profile "web":dsh-base + dsh-web-app + 第三方 @***@***.*** + dsh-experimental-agent-team-profile
- 追加实验包:dsh-browser-use / dsh-experimental-browser-use-playwright-mcp / dsh-computer-use / dsh-experimental-computer-use-cua-driver-native(均 0.1.7-alpha.1)
- 浏览器后端配置:mode=launch、headless=true、executablePath 指向本机 Edge
- 本机补丁:failOnStartupError true → false(唯一改动,位置见【4】)
========================================
【2】故障当天(2026-09-25,北京时间 UTC+8)时间线
========================================
19:56:20 Host PID 2464 启动
19:57:38 已有会话发起请求 → 该 Agent 工具清单含 24 个 mcp__playwright-mcp__*(挂载成功)
20:02:09 新建会话失败(原始日志见下)
20:05:10 再次失败,返回 {"ms":541, ...}
~20:09 同一 Host 内第 3 次新建会话尝试,同样失败(约 0.5 秒内返回)
20:10:36 用户重启服务 → Host PID 24532
20:11:51 该会话请求头 mcp__playwright-mcp__* = 0;20:12:51 = 24
20:10 之后 新建会话恢复正常
原始日志行(摘自 session.v4.jsonl.zstd,仅截取相关片段,会话 ID 保留前 8 位):
失败 1 —— [tool/result seq=390, 2026-09-25T12:02:09.340Z]
{"ok":false,"error":{"code":"gateway/internal","message":"failed to create session \"session-618c0ecc…\": Error: mcp-client(playwright-mcp): initial connection or tool synchronization failed","details":{}}}
失败 2 —— [tool/result seq=668, 2026-09-25T12:05:10.816Z]
{"ms":541,"ok":false,"err":{"code":"gateway/internal","message":"failed to create session \"session-e7f8fcae…\": Error: mcp-client(playwright-mcp): initial connection or tool synchronization failed"}}
抛出点 —— 在该会话里从已安装的 ***@***.*** 构建产物中检索到(lib/index.js:832):
if (outcome.error !== void 0 && config.failOnStartupError)
throw new Error('mcp-client(' + config.serverName + '): initial connection or tool synchronization failed', { cause: outcome.error });
同一文件中与 reconnect: { enabled: false } 配套的那条日志(约 560 行):
"connection failed and reconnect is disabled — no tools were registered; reload the plugin or restart the Host to connect"
即:重连被关闭时,官方设计的唯一恢复手段就是"重载插件或重启 Host";而 failOnStartupError: true 让这个失败在 Agent 创建路径上变成致命错误。
========================================
【3】A/B:同一 Host 内多个 Agent 的浏览器工具清单对比
========================================
(request/header 是每次模型请求实际下发的工具清单,可精确看出该 Agent 拿没拿到浏览器工具)
Host PID 2464(19:56:20 启动)
- 会话 628c2696 @ 2026-09-25T11:57:38Z → mcp__playwright-mcp__* = 24,第三方桥 browser_* = 11
- 新建会话 ×3 @ 12:02:09Z / 12:05:10Z / ~12:09Z → 创建即失败(见【2】)
Host PID 24532(20:10:36 启动)
- 会话 628c2696 @ 12:11:51Z → 0 ;@ 12:12:51Z → 24
- 会话 660e0169 @ 12:41:35Z → 24
Host PID 26644(09-26 00:46:24 启动)
- 会话 660e0169 @ 16:51:50Z → 24
- 会话 c9f6d41f(本次 A/B 新建)@ 16:58:13Z → 24
- 会话 660e0169 @ 17:01:45Z → 0
读法:
- 故障当天的签名 = "第一个 Agent 挂载成功,之后所有新建会话全部失败",与 host-runtime-duplication.spec.ts 用例 1 描述的签名一致。
- 之后两个 Host 里,多个 Agent 都能拿到 24 个工具(新模式下一次新建会话 + 已有会话同时各持 24 个),没有出现连坐。
- 数值在 0 / 24 之间切换与 exclusive 独占挂载语义一致(同一时刻只有一个 Agent 持有浏览器挂载)。这一栏不能当作"挂载失败"的证据,我按"独占交接"解读。
========================================
【4】failOnStartupError:true → false 的行为差异
========================================
补丁位置(profile 内的包,硬链接进两棵包树,物理上只有一个文件):
***@***.******@***.******@***.***/dsh-experimental-browser-use-runtime/lib/types/mcp.js
(对应源码 packages/experimental/browser-use-runtime/src/mcp.ts:152)
true(上游默认,rc.1 / rc.2 / master 均是)
- 挂载失败时该 Config 在 Agent 创建路径上抛出 → agent/created 失败 → session/create 返回 gateway/internal
- 影响范围是全局的:同一 Host 内此后每次新建会话都失败,直到重启 Host
- 实测:20:02:09、20:05:10 及第 3 次尝试全部失败;重启后立即恢复
- 恢复手段:只能重载插件或重启 Host(reconnect.enabled = false)
false(本机补丁)
- 错误被吞掉/记录,Agent 与会话照常创建,只是该 Agent 没有浏览器工具
- 影响范围是局部的:仅该次挂载不可用
- 实测:重启后新建会话正常;本次 A/B 中新建会话正常创建并拿到 24 个工具
差异是"致命 → 非致命",而不是"修好了":底层那次连接/同步失败是否发生、为什么发生,false 只是让它不再阻断会话创建。这也是我把诉求定为"故障隔离"而不是"配置问题"的原因。
========================================
【5】"升级到 rc.2 不改变这个行为"的证明
========================================
(npm pack 下载官方 tarball 后逐文件比对)
- @deepseek-ai/dsh-experimental-browser-use-runtime:alpha.1 vs rc.2 的 lib/types/mcp.js、lib/index.js、lib/types/index.js、lib/types/mcp.d.ts、README.md、README.zh.md、LICENSE 全部逐字节相同;仅 package.json、README.i18n.yaml 不同。产物内仍是 failOnStartupError: true + reconnect: { enabled: false }
- @deepseek-ai/dsh-scope:alpha.1 vs rc.2 的 lib/index.js 等逐字节相同;两版都仍是 const kScope = Symbol("dsh.scope")(每模块实例一枚,非 Symbol.for)
- master 源码:packages/experimental/browser-use-runtime/src/mcp.ts:152 = failOnStartupError: true,:153 = reconnect: { enabled: false }
- master 源码:packages/mcp/mcp-client/src/index.ts:201 = 你给的抛出点(已核对一致)
- 提交数:alpha.1→alpha.2 = 162,rc.1→rc.2 = 346(与你给的一致)
⇒ 这 508 个提交里没有触碰这条路径。
【5.2】#4573 方向核对:重复模块实例的前置条件在本机成立
- 宿主安装 ***@***.******@***.***/dsh-scope = 0.1.7-alpha.1
- profile 内 browser-use-runtime 解析到的 @deepseek-ai/dsh-scope = 0.1.0-rc.8(junction 目标实测)
- 同一目录下 @deepseek-ai/dsh-mcp-client 也是另一份物理拷贝(0.1.7-alpha.1)
- profile 的 pnpm-lock.yaml 中同时存在 ^0.1.0-rc.8 与 ^0.1.7-alpha.1 两条 dsh-scope 需求(前者来自第三方插件的旧依赖树)
========================================
【6】我尝试复现但没成功的记录(如实说明)
========================================
- 在两个后续 Host(PID 24532、PID 26644)里都没能复现连坐:【3】显示多个 Agent 各自拿到 24 个工具。
- 本次 A/B(Host PID 26644)操作:新建会话 → 正常创建、无报错提示;向其发送一条消息 → 该会话请求头含 24 个 playwright 工具;同时已有会话也保有 24 个;每个 Agent 各自拉起自己的 playwright-mcp 子进程(父进程均为存活 Host)。
- 进程快照(09-26 01:02–01:03 北京):playwright-mcp 子进程存在且父进程存活;msedge.exe 共 15 个进程,全部属于用户自己的 Edge 浏览器(进程树根父进程 explorer.exe,--user-data-dir 指向常规用户配置目录),headless / playwright 相关 msedge = 0,即当前没有孤儿浏览器进程。
- 一条观察(未形成结论):00:57–01:03 之间 playwright-mcp 子进程的 PID 多次变化,看起来挂载在会话之间交接时会被反复拆装。
- 结论:host-runtime-duplication 是真实的潜在缺陷(前置条件成立、机制被你们自己的用例钉住),但需要一个我还没找到的额外触发条件才会变成致命;"陈旧状态/资源累积"这个方向,我这台机器上目前没有孤儿进程可以佐证。
========================================
【7】需要你们判断的三点
========================================
1) 在 failOnStartupError: true + reconnect.enabled: false 的组合下,"某次连接失败后该 Host 内所有新建会话持续失败直到重启"是否是预期行为?session/create 是否应降级为"该会话没有浏览器工具 + 明确提示"?
2) 【5.2】的重复模块实例是否就是那次连接/同步失败的来源?如果是,倾向修 dsh-scope 的模块身份(Symbol.for),还是让 profile 不再携带第二份?
3) 能否把底层 cause 暴露到错误文案或 Host 日志?(这条对定位帮助最大)
需要补充材料我可以再取:故障当天的完整会话日志片段、任一 Host 的完整进程树快照,或按你们指定的实验步骤在隔离实例上跑一遍。
|
你的结论我独立核过了:成立——
|
|
收到,谢谢独立核验——用提交历史来证比我的产物哈希更直接(说明一下我这边的方法:npm pack 解包后对 alpha.1 / rc.2 两版逐文件比对哈希)。
按你们的两点措辞建议,最终诉求定稿如下:
【诉求(可判定的两条)】
1. session/create 不应因单个可选工具的挂载失败而失败(不应返回 500);该工具应被标记为不可用,并在该会话内明确提示。
2. 错误文案与 Host 日志应带出底层 cause:现在 gateway/internal 只给通用文案,定位只能停在"必然以同一文案失败"这一层。
【关于"作用域"那层区分,我按当前 master 的源码补一个更精确的落点】
packages/experimental/browser-use-runtime/src/mcp.ts:
- :177 注册 agent/created({ prepend: true })
- :188 await resources.get(agent, signal)
- :129 open()
- :144 await scope.ctx.plugin(McpClient, McpClient.Config({ …, failOnStartupError: true, reconnect: { enabled: false } }))
即这个"可选"能力的挂载被 await 在会话创建的钩子里,失败即 reject 出去,实测表现为 gateway/internal: failed to create session …;而 reconnect: { enabled: false } 让它不会自愈,所以同一 Host 内后续每次创建都失败,直到重启 Host。
另外,同一个函数里已经有"优雅降级"的分支::183–187 在资源被占用时只把状态置为 blocked 然后 return(该会话没有浏览器工具、但不报错)。既然"工具不可用但不影响会话"这条路已经实现,挂载失败完全可以走同一条路——所以建议改的是失败允许传播的边界,而不是 failOnStartupError 的语义("这个工具没有就别静默降级"我认同是合理的设计意图)。
【状态】
本机已升到 0.1.7-rc.2(隔离实例试跑后切换,升级本身正常),本地那个 true → false 的补丁仍在位、连坐暂时被压住;按你们的意见我不再做"最新版上复现",保持观察。需要我按指定步骤跑实验时说一声即可。
(dsh-scope 重复实例那条 #4573 我仍无法稳定复现;如果能给出必然触发的条件,我可以照着构造实验。)
|
Uh oh!
There was an error while loading. Please reload this page.
您好,今天我开机后在后台干净的情况下启动dsh终端进入web页面,发现工作区无法创建新对话,且点击已有对话会直接消失(后证明被自动归档),我找到一个还能对话的聊天让它帮我排查修复,他排查后发现是浏览器工具(Playwright MCP)的启动失败会连坐整个会话创建,本机通过把那个插件的 failOnStartupError 从 true 改成 false后新对话创建恢复正常,以下是dsh写的反馈报告
环境
0.1.7-alpha.1(npm 安装,2026-09-22)win32,Nodev24.18.0)profile/cordis.yml):@playwright/mcp:0.0.80(profile 内.pnpm安装)~/.dsh/profiles/web)各有一份@deepseek-ai/dsh-mcp-client@0.1.7-alpha.1(下面第 5 点的钩子没生效,可能与此有关,供参考)影响
session/create返回 500复现(未能稳定复现,见下)
已观测到的最短序列:
POST /api/session/create(body:{"type":"client-request","rpcId":"<uuid>","method":"session/create","payload":{"args":{"request":{"workspaceId":"<id>"}}}})同一台机器上无法稳定复现:用同一份配置、同一个
@playwright/mcp@0.0.80、同一个executablePath、同一个cwd离线执行一次等价的 MCP 挂载,483 ms 成功并注册 24 个工具。因此怀疑是常驻 Host 进程内部的连接/挂载状态问题,而不是配置或环境错误。实际表现
session/create连续 3 次失败,报错一致:耗时分别 541 ms / 513 ms / 500 ms(约 500 ms 即失败,不像握手超时)。
taskkill /T /F清理。此外每个会话会各自拉起一个playwright-mcp进程 + 一个隔离 headless Edge,部分进程在会话结束后仍常驻。疑似根因
@deepseek-ai/dsh-experimental-browser-use-runtime的mountSessionMcp()在 Agent 创建流程内同步等待 MCP 挂载:packages/experimental/browser-use-runtime/src/mcp.ts@deepseek-ai/dsh-mcp-client随后在启动失败时抛错:packages/mcp/mcp-client/src/index.ts结果:浏览器工具(实验性、可选能力)的一处启动失败,会让整个会话创建失败;同时
reconnect: { enabled: false }意味着失败后不会自愈,该 Host 进程会持续表现为“无法新建会话”,只能重启。相关资源泄漏
--isolated的 headless 浏览器在崩溃/会话结束后可能变成孤儿进程并常驻(本次实测 12 个 Edge 进程、约 1.5 GB)本地规避手段
把该处改为
failOnStartupError: false后,浏览器工具即使启动失败也只会“该会话没有浏览器工具”,不再阻塞会话创建。但这只是掩盖症状,浏览器工具本身仍然不可用。建议
agent/created钩子里容错)reconnect(当前enabled: false,失败后不自愈)playwright-mcp进程与隔离浏览器进程树被清理,不留孤儿进程cause(包括 MCP 子进程 stderr),现在只有initial connection or tool synchronization failed,用户侧无法定位其他
本机无法稳定复现,所以没有最小复现工程。如果能告诉我需要采集哪些诊断信息(例如让
dsh-mcp-client输出子进程 stderr、插件加载顺序,或是否存在并发挂载竞争),我可以按需补充。All reactions