Replies: 3 comments
|
核验通过(对照 main/master HEAD 1. 代码确认。 2. 修复正确:把回退条件扩展为 3. 建议补两件事:
需要的话我可以把这个 1 行修复 + 回归测试做成 cherry-pick 分支(按之前的惯例)。 |
|
cherry-pick 分支已建好(含回归测试): https://github.com/zoahdev/deepseek-harness/tree/fix/atomic-write-eacces-fallback
PR 通道开放时可直接 cherry-pick;若你想按自己仓库流程提交也随意使用。 |
|
I published an operator-focused recovery runbook for this failure, pinned to upstream https://sandbaseai.github.io/deepseek-harness-handbook/windows-replacefile-eacces.html One source-detail correction for anyone implementing the proposed upstream patch: the helper at that revision is named For operators who need a safe path before a fix ships, the bounded lifecycle is: stop the exact HMR owner → record |
Uh oh!
There was an error while loading. Please reload this page.
Summary
On Windows, the
edittool (andwriteover an existing file) fails withReplaceFileW EACCES (Win32 5)whenever the target file is being watched by the harness's own HMR (cordis-plugin-hmr→ chokidarfs.watchon profile config files). Writing new files works fine; replacing existing, watched files fails consistently. The identical replacement viarename(MoveFileExW) succeeds under the same conditions — the failure is specific toReplaceFileWsemantics on a file that has an open watcher handle.Environment
0.1.0-rc.7(@deepseek-ai/dsh,@deepseek-ai/dsh-fs-local)C:\Users\Administrator\.dsh\profiles\web\cordis.patch.yml(watched by HMR)Repro steps
dsh web.edit~/.dsh/profiles/web/cordis.patch.yml(existing, HMR-watched file).Error: ReplaceFileW EACCES (Win32 5): C:\Users\Administrator\.dsh\profiles\web\cordis.patch.ymlattrib/icacls).Root cause
dsh-fs-local'swriteFileAtomicpublishes on win32 viaReplaceFileW(kernel32). When the destination has an open watcher handle (chokidar/fs.watchused bycordis-plugin-hmron profile config files),ReplaceFileWreturnsERROR_ACCESS_DENIED(5), whileMoveFileExW(MOVEFILE_REPLACE_EXISTING)succeeds.Verified by calling the Windows API directly with the same FFI (
koffi) thatdsh-fs-localuses:ReplaceFileWrename(MoveFileExW)fs.watchhandle open on targetSuggested fix
In
dsh-fs-local/lib/index.jswriteFileAtomic, the win32 branch already falls back torename()whenReplaceFileWfails withENOENT; extend the fallback to also coverEACCES(the watched-target case):A genuinely locked/denied target also fails the
renamefallback, so this cannot mask a real access problem. Note thecopyFileDaclstep beforeReplaceFileWalready copies the target ACL onto the staging file, so the rename path retains the ACL intent.Related observation
A child process running
dsh --profile web(profile-bootprepareProfile→writeFileSync(cordis.yml)) can also hitEPERM ... open ...cordis.ymlwhen the parent holds a watch handle on the profile root file — same underlying watcher-handle conflict.Workaround (until fixed)
Edit watched config files via a new patch/overlay file (new files are unaffected), or via
pwsh Set-Content, or fall back to rename.All reactions