fix(filesystem): harden file replacement with EPERM fallback#3610
fix(filesystem): harden file replacement with EPERM fallback#3610Chelebii wants to merge 3 commits intomodelcontextprotocol:mainfrom
Conversation
Extract replaceFileFromTemp helper that falls back to fs.cp when fs.rename fails with EPERM (Windows locked files). Temp file cleanup is best-effort so a successful write is never masked by a cleanup failure (e.g. antivirus holding the temp file). Changes: - Extract replaceFileFromTemp from inline rename logic in writeFileContent and applyFileEdits - Add EPERM fallback: rename -> cp + best-effort unlink - Document FILE_SHARE_DELETE limitation and non-atomic fallback in JSDoc - Add tests for EPERM fallback through both writeFileContent and applyFileEdits - Add tests for successful writes despite temp cleanup failure Fixes modelcontextprotocol#3430
|
Follow-up: all checks are now passing after the lockfile refresh commit (c22fad2). The earlier Python failure was caused by src/fetch/uv.lock being out of sync with src/fetch/pyproject.toml, and that is now resolved.\n\nAt this point the PR looks blocked only on maintainer review / merge, not on CI. |
|
@codex review focus on bugs, edge cases and missing tests |
|
@claude review |
|
Claude finished @cliffhall's task in 1m 49s —— View job Code Review
Overall this is a clean, well-motivated change. The refactoring reduces duplication, the JSDoc is excellent, and the new tests cover the primary scenarios. There are a couple of real issues worth addressing before merge. Bug: orphaned temp file when
|
|
Addressed the Claude review feedback in What changed:
Validation:
|
Problem
When \s.rename\ fails with \EPERM\ on Windows (e.g. VS Code or antivirus holding a file lock), both \writeFileContent\ and \�pplyFileEdits\ propagate the error even though the write could succeed via a fallback path. Additionally, if the fallback copy succeeds but temp file cleanup fails (antivirus briefly locks the temp), the user sees an error despite the target file being written correctly.
Ref: #3430, #3199
What changed
eplaceFileFromTemp\ helper from the inline rename logic in \writeFileContent\ and \�pplyFileEdits, eliminating code duplication.
Validation
\
npx vitest run
✓ tests/lib.test.ts (49 tests)
✓ tests/path-utils.test.ts (29 tests)
✓ tests/roots-utils.test.ts (3 tests)
✓ tests/path-validation.test.ts (53 tests)
✓ tests/directory-tree.test.ts (7 tests)
✓ tests/structured-content.test.ts (5 tests)
✓ tests/startup-validation.test.ts (4 tests)
Test Files 7 passed (7)
Tests 150 passed (150)
\\
\ sc --noEmit\ — 0 errors.
Checklist (from #3430)
eplaceFileFromTemp)
Fixes #3430