Repository navigation
[Bug] 桌面版「在编辑器中打开」对 Electron 系编辑器必然失败 —— ELECTRON_RUN_AS_NODE 泄漏到子进程 #9599
Replies: 1 comment
|
Mechanism confirmed in the tree — and the two-arm experiment you ran (same binary, same argv, one variable different) is what makes this immediately actionable.
Three things worth adding: 1. The pattern is "allow everything that is not credential-shaped", and that cannot express "do not forward host-runtime control variables". So each such variable is a separate bug, and this one is worse than a leak: the forwarded name is not a credential but a process-mode switch, which is why the outcome is a hard 502 on a healthy-looking install rather than a suspected-secret. The general shape that stops the class is an explicit deny list of interpreter/electron runtime switches ( 2. This one is not plugin-reachable, so it needs an in-tree change. The scrub is core ( 3. The failure is arguably worse than "the button does not work". Because Your diagnosis of the exit path ( |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
环境
0.2.0-rc.2(nightly 通道)@deepseek-ai/dsh-host-open-in-app@0.2.0-rc.2现象
会话页右上角的「在 VS Code 中打开」按钮点击后必然失败,界面提示打开失败。
接口层面直接可复现:
注意:应用探测是正常的 ——
GET /open-in-app/apps正确返回{"apps":["explorer","vscode"]},说明按钮和 VS Code 条目都在,失败只发生在启动这一步。
根因
DSH 桌面版用
ELECTRON_RUN_AS_NODE=1把宿主当纯 Node 运行(
desktopNodeEnvironment()显式设置该变量),因此这个变量常驻宿主进程环境。启动外部应用时,
launchDetachedApp用scrubbedParentEnv()构造子进程环境:而
scrubbedParentEnv()(@deepseek-ai/dsh-subprocess)只过滤两类:即「凭据类变量(
*KEY*/*SECRET*/*TOKEN*/*PASSWORD*)」和「DSH_前缀」。ELECTRON_RUN_AS_NODE两条都不匹配,因此被原样传给被启动的程序。VS Code 的
Code.exe本身也是 Electron,看到该变量就不启动 GUI,改以 Node 模式运行,把工作区路径当作 JS 入口脚本去 require:
进程随即以退出码 1 结束。而
launchDetachedApp的监视逻辑规定:→ 在监视窗口内非 0 退出即判为失败 → 路由返回 502 → 前端报错。
复现 / 对照实验
同一个可执行文件、同样参数,只差一个环境变量:
ELECTRON_RUN_AS_NODE=1(DSH 的实际行为)Error: Cannot find module '<工作区>',VS Code 不出现影响面
explorer(文件管理器)等非 Electron 应用因此菜单里的「在文件管理器中显示」是好的,只有 Electron 系编辑器打不开。
在 Windows 桌面上该问题 100% 复现;非桌面入口(如从普通终端启动)也可能受影响,因为
dsh的命令包装脚本本身也会设置该变量。建议修复
最小改动 —— 在合并适配器显式
options.env之前剔除继承来的该变量:const child = spawn(command, [...args], { detached: true, stdio: "ignore", windowsHide: options.windowsHide, - env: { - ...scrubbedParentEnv(), - ...options.env - } + env: ((inherited) => { + delete inherited.ELECTRON_RUN_AS_NODE; + return { ...inherited, ...options.env }; + })(scrubbedParentEnv()) });顺序很关键:必须在合并
options.env之前清除。因为 catalog 里已有条目(如 GitHub Desktop)故意声明
env: { ELECTRON_RUN_AS_NODE: "1" }来运行它自己的cli.js;若在合并之后删除,会破坏那类条目。另一种等效做法是给 catalog 中 vscode / cursor / windsurf 等 GUI Electron 条目加
env: { ELECTRON_RUN_AS_NODE: undefined },利用已有的options.env覆盖机制。临时绕过(用户侧)
无需改代码即可先用起来:
附:诊断用到的可观测点
GET /open-in-app/apps→ 应用探测结果(本例为正常)POST /open-in-app/open→ 启动结果与失败码(本例 502launch-failed)All reactions