Skip to content

fix(io): copy-fallback for atomic writes on cross-device (EXDEV) rename#2696

Merged
esengine merged 1 commit into
main-v2from
fix/exdev-rename-fallback
Jun 2, 2026
Merged

fix(io): copy-fallback for atomic writes on cross-device (EXDEV) rename#2696
esengine merged 1 commit into
main-v2from
fix/exdev-rename-fallback

Conversation

@esengine
Copy link
Copy Markdown
Owner

@esengine esengine commented Jun 2, 2026

Closes #2694

What

Make atomic file writes survive Windows encryption-software filter drivers (亿赛通/Esafenet and similar), which reject the temp-file → target rename with a cross-device link error (EXDEV) even when both paths are in the same directory.

Why

The session save, conversation-branch metadata, config save (reasonix setup / /mcp add / /thinking), and the desktop .env / session-title / display saves all write to a sibling temp file and then os.Rename it onto the destination. On machines with these drivers that rename fails, so the save fails.

Note on #2694: the report's /apply "edit blocks" trace is from the v1 (Node) line — its EXDEV: ... rename string and write-file-atomic temp names are libuv's. In v2 the write_file / edit_file / multi_edit tools already write in place (os.WriteFile), so the edit path was never affected. The same failure mode does exist in v2's rename-based atomic saves, which this fixes.

How

New fileutil.ReplaceFile(tmp, dest): renames as before, and only if the rename fails, copies the temp file's bytes onto the destination (re-applying the temp's mode so a 0600 config temp doesn't widen) and removes the temp — the copy path the drivers permit. The original rename error is surfaced only if the copy fallback also fails, so genuine failures aren't masked. Routed the five rename sites (agent/save.go, agent/branch.go, config/edit.go, desktop/dotenv.go, desktop/sessions.go) through it.

codegraph/install.go also renames, but that's a directory move during install (a different, recursive case) and out of scope here.

Tests

internal/fileutil unit tests cover the rename happy path and the copy fallback (full overwrite of a longer destination + temp removal + mode). Runs on all three OS legs including windows-latest. Desktop module builds and its session tests pass.

…evice link

Windows encryption-software filter drivers (e.g. 亿赛通/Esafenet) intercept the temp-file -> target rename that the session, branch, config, and desktop .env/title saves use, returning a cross-device link (EXDEV) even within one directory. The save then fails. Add fileutil.ReplaceFile: it renames as before and, only when that fails, copies the temp file's bytes onto the destination (preserving mode) and removes the temp — the path the encryption drivers allow. Route the rename sites through it. The edit/write tools already write in place, so they were never affected.
@github-actions github-actions Bot added the v2 Go rewrite (1.x) — main-v2 branch, active development label Jun 2, 2026
@esengine esengine merged commit c7b119e into main-v2 Jun 2, 2026
5 checks passed
@esengine esengine deleted the fix/exdev-rename-fallback branch June 2, 2026 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: 安装亿赛通等加密软件时-/apply的跨磁盘rename指令会报错

1 participant