Skip to content

fix(deepagents): edit_file reports initial-content write, not '0 occurrence(s)', on empty files - #635

Open
Andrew Kondratev (andruhon) wants to merge 1 commit into
langchain-ai:mainfrom
andruhon:fix/edit-file-empty-init-message
Open

Andrew Kondratev (andruhon) wants to merge 1 commit into
langchain-ai:mainfrom
andruhon:fix/edit-file-empty-init-message

Conversation

@andruhon

Copy link
Copy Markdown

Summary

Follow-up to #161. That issue was the occurrences = -1 bug when both the file content and old_string are empty; the fix added an intentional "set initial content" special case in performStringReplacement that returns [newString, 0] — the content is written, and occurrences is 0.

The success message for that path was never updated, so edit_file on an empty file now reports:

Successfully replaced 0 occurrence(s) in '<path>'

The content was written correctly, but the message describes a no-op replacement. Because edit_file results are consumed by an LLM, an agent that writes initial content into an empty file reads "replaced 0 occurrence(s)" and reasonably concludes the write failed — retrying, switching tools, or reporting it as a bug. (We hit exactly this during manual testing: an agent flagged "edit_file succeeded but reported 0 occurrences despite writing content" as a suspected harness anomaly.)

Change

Branch the edit_file success message on result.occurrences === 0:

Successfully wrote initial content to '<path>'

This is safe because a genuine zero-match on a non-empty file returns Error: String not found in file before the success message is built (and an empty old_string on a non-empty file returns Error: oldString cannot be empty). So the only non-error path that reaches the message with occurrences === 0 is the empty-file init case — where content really was written.

Tests

Added two deterministic tests in fs.permissions.test.ts (mock-backend harness, no live model):

  • occurrences: 0 → message contains "initial content" and not "0 occurrence(s)"
  • occurrences: 1 → message still reports "replaced 1 occurrence(s)"

vitest run src/middleware/fs.permissions.test.ts → 31 passed, no type errors.

Notes

  • Message-only change; no behavior change to what gets written.
  • Verified against [email protected] (the shipped Successfully replaced … template and the content === "" && oldString === "" special case are both present in the published bundle) and on current main.

…)', on empty files

When edit_file runs on an empty file with an empty old_string,
performStringReplacement takes the intentional init special case (added in
the fix for langchain-ai#161) and returns [newString, 0]: the content IS written, but
the tool reported `Successfully replaced 0 occurrence(s)`. That reads like a
no-op and misleads LLM agents into thinking the write failed / retrying.

Branch the success message on occurrences === 0 — the only non-error path
that reaches it, since a genuine no-match returns 'String not found' before
this point — to report `Successfully wrote initial content to '<path>'`.

Adds deterministic tests for both the init-path message and the normal
replacement-count message.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@changeset-bot

changeset-bot Bot commented Jul 1, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d9d3348

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

Andrew Kondratev (@andruhon) is attempting to deploy a commit to the LangChain Team on Vercel.

A member of the Team first needs to authorize it.

@pkg-pr-new

pkg-pr-new Bot commented Jul 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

deepagents-acp

npm i https://pkg.pr.new/deepagents-acp@635

deepagents

npm i https://pkg.pr.new/deepagents@635

@langchain/sandbox-standard-tests

npm i https://pkg.pr.new/@langchain/sandbox-standard-tests@635

@langchain/daytona

npm i https://pkg.pr.new/@langchain/daytona@635

@langchain/deno

npm i https://pkg.pr.new/@langchain/deno@635

@langchain/modal

npm i https://pkg.pr.new/@langchain/modal@635

@langchain/node-vfs

npm i https://pkg.pr.new/@langchain/node-vfs@635

@langchain/quickjs

npm i https://pkg.pr.new/@langchain/quickjs@635

commit: d9d3348

@andruhon Andrew Kondratev (andruhon) changed the title fix(fs): edit_file reports initial-content write, not '0 occurrence(s)', on empty files fix(deepagents): edit_file reports initial-content write, not '0 occurrence(s)', on empty files Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant