Repository navigation
[Bug] session 的 openWorkspacePath / workspacePathApplications 一律拒绝「路径中含 junction 或符号链接」的文件(0.2.0-rc.2,Windows,报 Path has no verified Host path) #9697
Replies: 3 comments
|
你这条完全成立 —— 机制、判定、零测试覆盖三项我都核过了。而且它比"链接路径不能打开"更严重一点:这四处入口共用同一个判定,所以是整族功能一起坏。我补三样你没写进来的证据。 1. ✅ 判定逐字核实(
|
|
三条我都回去核了,两条成立,一条是我表述不够严谨,先致谢——尤其是你把 1. 全历史核实:
|

Uh oh!
There was an error while loading. Please reload this page.
运行环境 / Environment
DSH Web(Desktop 壳内,web profile)· Windows 11 x64 · Electron 44.0.0 · Node v24.18.1
版本 / Version
@deepseek-ai/dsh0.2.0-rc.2(npmlatest)。app.asar内dsh-api-session-controller/lib/index.js、dsh-fs-local/lib/index.js与本节引用行号一一对应。最新代码未修(
master@5719020,2026-10-14,"sync dsh 0.2.1-alpha.3"):packages/api/session-controller/src/index.ts:412-423的判定逐字未变;该文件tests/session-open-workspace-path.host.spec.ts里 symlink / junction / realpath 零覆盖。全历史里verifyDesktopPath只被动过一次(39bde1a,feat: query file applications for sidebar opening (#4562))——那次只是把内联判定抽成这个私有方法,realpath 相等比较原样搬过来,没有任何链接相关处理。是否已有人报过 / Related reports
按关键词(
junction/symlink/符号链接/openWorkspacePath/workspacePathApplications/打开方式/在应用中打开/无法打开/path open failed)扫过仓库 3800 条 Discussion(RESTlist-discussions,第 38 页后触发匿名限流),没有与「链接下的文件无法打开 / 无法列出关联应用」完全相同的条目。最接近的两条症状不同,可作为补充参考:如果这条与上面某条其实同源,请直接合并处理。
现象 / What happened
工作区里只要有一个目录联接(junction)或符号链接,对它下面任何文件做「用某个应用打开」「在文件管理器中显示」这类操作,宿主一律拒绝:
用户侧看到的是「无法打开:<该文件路径>」。同一个工作区里、不在链接目录下的文件完全正常,所以这不是权限、不是关联应用缺失,也不是路径拼错——被拒的路径确实存在、确实可读。
复现实例(工作区
<WS>,下同;<REAL>是链接的目标目录):<WS>\docs\notes.md存在、可读;<WS>\README.md(同工作区、非链接路径)右键 → 同样操作:成功。宿主自己的
dsh-client-ui-open-in-app(lib/client.js里同样调remote.session.openWorkspacePath/workspacePathApplications)和dsh-better-sidebar的文件树都会走到这条判定上,所以两处一起坏。根因 / Root cause
@deepseek-ai/dsh-api-session-controller的verifyDesktopPath():等式右边是词法路径,左边是 realpath:
@deepseek-ai/dsh-fs-local的resolveLocalTarget()(lib/index.js:169-176)在存在性探测成功时返回targetKey: FsTargetKey(await realpath.native(displayPath))——目标是按 realpath 认身份的(realpath.native在 Windows 上就会展开 junction / 符号链接);processPath(target)(同文件:789-791)返回的正是这个targetKey。因此对链接路径:
hostPath = resolve(request.path)<WS>\docs\notes.mdfs.resolve(mapped).targetKey<REAL>\notes.md两者永不相等 → 抛
gateway/bad-request。本机可直接核对这一对值(<WS>换成自己的工作区):这不是安全判定失败——
mapped !== undefined且 realpath 成功,说明「宿主确有这个文件」已经成立;挂掉的只是最后那次字符串相等比较。语义上它把「同一个文件的两个等价拼写」误判成「不是宿主路径」。影响面 / Impact
同一函数被下列入口共用,凡是请求路径经过 junction / symlink(Windows 上很常见:
mklink /J的目录、OneDrive/坚果云的占位目录、pnpm 的 store 链接、把docs之类目录外置到另一个盘的常见做法)都一并失效:session.openWorkspacePath({path})(用默认应用打开)session.openWorkspacePath({path, application})(用指定应用打开)session.openWorkspacePath({path, action: 'reveal'})(在文件管理器中显示)session.workspacePathApplications({path})(列出可打开该文件的应用——列表阶段就失败,所以插件连菜单项都画不出来)期望行为 / Expected behavior
verifyDesktopPath()只应回答「这个路径是不是宿主上真实存在的那个文件」,不应要求请求方猜测宿主的拼写。链接路径与其目标是同一个文件,两者都必须通过。建议修法 / Suggested fix
把比较放在同一套 canonical 形式上,任选其一:
(
FsResolvedPath同时带displayPath与targetKey,所以两种口径都拿得到;核心是别再拿 realpath 去等于词法路径。)复现步骤 / Steps to reproduce
cmd /c mklink /J <WS>\docs <REAL>;<REAL>放一个普通文件,例如notes.md;<WS>为工作区开会话,确认<WS>\docs\notes.md能在文件树里列出并正常读到内容;Path has no verified Host path(界面侧表现为「无法打开:\docs\notes.md」);同一棵树里<WS>\下的其它文件没有这个问题。补充信息 / Additional context
dsh-better-sidebar@0.26.0的文件树上肉眼复现的;该插件只是把文件树里的路径原样交给remote.session.*,没有自己的路径改写或路径白名单(插件文档明确写着 v0.23.0 起已删除工作区包含检查),所以修复点不在插件侧。verifyDesktopPath()与 0.2.0-rc.2 逐字相同,同样受影响。verifyDesktopPath里的两个值各打一行日志即可自证(hostPathvsfs.processPath(await fs.resolve(mapped)))。All reactions