From fbb7e742629480942b265593f290763005ba5291 Mon Sep 17 00:00:00 2001 From: rareboe Date: Mon, 14 Sep 2026 11:23:11 +0900 Subject: [PATCH] fix(core): describe the real cause of the edit stale-content failure FileMutation.StaleContentError is raised by writeIfUnchanged purely on a byte comparison under the per-path lock, and carries only a path. It fires whenever anything writes the file inside the edit's read to write window, from any session or process. The edit tool was the only place mapping it, and the mapping invented a cause the error never knew about: "File changed after permission approval." That misdirects anyone debugging a concurrent write, which is the common case. The existing regression test shows this directly. It is named "rejects an in-place content change after matching but before conditional commit" and simulates a plain concurrent write, yet asserted the permission wording. Name the actual condition instead and keep the same remedy. --- packages/core/src/tool/edit.ts | 2 +- packages/core/test/tool-edit.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/tool/edit.ts b/packages/core/src/tool/edit.ts index f0bdb488a060..a11dc8023257 100644 --- a/packages/core/src/tool/edit.ts +++ b/packages/core/src/tool/edit.ts @@ -112,7 +112,7 @@ const layer = Layer.effectDiscard( Effect.mapError((error) => error instanceof FileMutation.StaleContentError ? new ToolFailure({ - message: "File changed after permission approval. Read it again before editing.", + message: "File changed since it was read. Read it again before editing.", }) : new ToolFailure({ message: `Unable to edit ${input.path}` }), ), diff --git a/packages/core/test/tool-edit.test.ts b/packages/core/test/tool-edit.test.ts index a9e4cbae4952..907b6f191fd9 100644 --- a/packages/core/test/tool-edit.test.ts +++ b/packages/core/test/tool-edit.test.ts @@ -398,7 +398,7 @@ describe("EditTool", () => { Effect.gen(function* () { expect(result).toEqual({ type: "error", - value: "File changed after permission approval. Read it again before editing.", + value: "File changed since it was read. Read it again before editing.", }) expect(yield* Effect.promise(() => fs.readFile(target, "utf8"))).toBe("newer\n") expect(writes).toEqual([])