Skip to content

Comments

fix(core): prevent omission placeholder deletions in replace/write_file#19870

Merged
bdmorgan merged 4 commits intogoogle-gemini:mainfrom
nsalerni:issue-19858
Feb 22, 2026
Merged

fix(core): prevent omission placeholder deletions in replace/write_file#19870
bdmorgan merged 4 commits intogoogle-gemini:mainfrom
nsalerni:issue-19858

Conversation

@nsalerni
Copy link
Contributor

@nsalerni nsalerni commented Feb 22, 2026

Summary

Prevents a reported failure mode where edit/write proposals replace unchanged code with omission placeholders like (rest of methods ...), which shows up as large unintended deletions in diffs.

This PR adds validation guardrails in replace and write_file, strengthens model-facing tool descriptions to forbid omission placeholders, and adds regression coverage for the issue pattern.

Details

The issue described model edits that replace unchanged code with placeholder lines like (rest of methods ...), causing large red deletions in diffs. This fix now blocks those payloads at tool validation time in both:

replace (new_string)
write_file (content)

So those placeholder-based edits no longer execute, which prevents that class of misleading diff/deletion.

It’s targeted to standalone omission-placeholder lines (the problematic pattern), not arbitrary ... inside normal code/string literals.

  • Added a new detector utility:
    • packages/core/src/tools/omissionPlaceholderDetector.ts
    • Detects standalone omission placeholders (case-insensitive), including:
      • (rest of methods ...)
      • (rest of code ...)
      • (unchanged code ...)
      • // rest of methods ...
  • Enforced detector in tool validation:
    • packages/core/src/tools/edit.ts
      • Rejects new_string omission placeholders unless the same placeholder is already present in old_string.
    • packages/core/src/tools/write-file.ts
      • Rejects omission placeholders in content.
  • Updated tool-definition descriptions to explicitly prohibit omission placeholders:
    • packages/core/src/tools/definitions/model-family-sets/gemini-3.ts
    • packages/core/src/tools/definitions/model-family-sets/default-legacy.ts
  • Added/updated tests:
    • packages/core/src/tools/omissionPlaceholderDetector.test.ts
    • packages/core/src/tools/edit.test.ts
    • packages/core/src/tools/write-file.test.ts
  • Updated snapshots for tool definitions:
    • packages/core/src/tools/definitions/__snapshots__/coreToolsModelSnapshots.test.ts.snap

Regression proof:

  • In a detached temp worktree at the pre-change commit, newly added regression assertions failed:
    • EditTool.validateToolParams returned null (no rejection) for placeholder-containing new_string.
    • WriteFileTool.build did not throw for placeholder-containing content.
  • After this change, those scenarios pass in the updated test suites.

Related Issues

Fixes #19858

How to Validate

  1. Run detector tests:

    • npm run test --workspace @google/gemini-cli-core -- src/tools/omissionPlaceholderDetector.test.ts
    • Expected: all tests pass.
  2. Run edit tool tests:

    • npm run test --workspace @google/gemini-cli-core -- src/tools/edit.test.ts
    • Expected: all tests pass, including regression test rejecting multiline omission placeholders.
  3. Run write-file tool tests:

    • npm run test --workspace @google/gemini-cli-core -- src/tools/write-file.test.ts
    • Expected: all tests pass, including regression test rejecting multiline omission placeholders.
  4. Run tool-definition snapshot test:

    • npm run test --workspace @google/gemini-cli-core -- src/tools/definitions/coreToolsModelSnapshots.test.ts
    • Expected: passes with updated snapshots.

Edge cases covered by tests:

  • Placeholder text inside normal code/string literal is not flagged.
  • Placeholder rejection triggers for standalone omission-style lines.
  • replace allows pass-through only when the same placeholder is already in old_string.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

Breaking changes:

  • None in public CLI API/commands.
  • Behavioral tightening: replace/write_file now reject omission-placeholder payloads during validation.

Add guardrails that reject standalone omission placeholders (for example
`(rest of methods ...)`) in `replace.new_string` and `write_file.content`,
while allowing pass-through when the same placeholder already exists in
`replace.old_string`. Also tighten model-facing tool descriptions and add
regression coverage.

Regression proof:
- Before this fix (tested in a detached temp worktree at the pre-change commit),
  new regression assertions failed:
  - `EditTool.validateToolParams` regression expected omission-placeholder error, got `null`
  - `WriteFileTool.build` regression expected throw, but no error was thrown
- After this fix, the same regression scenarios now pass.

Tests:
- `npm run test --workspace @google/gemini-cli-core -- src/tools/omissionPlaceholderDetector.test.ts`
- `npm run test --workspace @google/gemini-cli-core -- src/tools/edit.test.ts`
- `npm run test --workspace @google/gemini-cli-core -- src/tools/write-file.test.ts`
- `npm run test --workspace @google/gemini-cli-core -- src/tools/definitions/coreToolsModelSnapshots.test.ts`

Fixes google-gemini#19858
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @nsalerni, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical issue where AI models inadvertently introduced large, misleading deletions in code by replacing unchanged sections with omission placeholders. The changes introduce robust validation mechanisms within the core replace and write_file tools, ensuring that such placeholders are rejected. This significantly improves the reliability and accuracy of code modifications generated by the system, preventing erroneous diffs and enhancing the developer experience.

Highlights

  • Prevented Omission Placeholder Deletions: Implemented validation guardrails in replace and write_file tools to prevent unintended deletions caused by models replacing unchanged code with omission placeholders like '(rest of methods ...)'. This addresses a reported failure mode where such placeholders led to large, misleading diffs.
  • New Omission Placeholder Detector: Introduced a new utility, omissionPlaceholderDetector.ts, to accurately identify standalone omission placeholders (e.g., '(rest of methods ...)', '// rest of code ...') in a case-insensitive manner. This detector is crucial for the new validation logic.
  • Enhanced Tool Validation: Integrated the new detector into the EditTool and WriteFileTool validation processes. The EditTool now rejects new_string containing omission placeholders unless the same placeholder was already present in old_string. The WriteFileTool rejects content containing any omission placeholders.
  • Updated Tool Descriptions: Modified the descriptions for new_string in replace and content in write_file within the tool definitions (gemini-3.ts, default-legacy.ts) to explicitly instruct models to avoid using omission placeholders and to provide exact literal code.
  • Comprehensive Test Coverage: Added new unit and regression tests for the omissionPlaceholderDetector, EditTool, and WriteFileTool to ensure the correct detection and rejection of omission placeholders, including scenarios where placeholders are allowed (e.g., within string literals or when old_string already contains the placeholder).
Changelog
  • packages/core/src/tools/definitions/snapshots/coreToolsModelSnapshots.test.ts.snap
    • Updated the snapshot to reflect changes in the new_string and content parameter descriptions for replace and write_file tools, explicitly forbidding omission placeholders.
  • packages/core/src/tools/definitions/model-family-sets/default-legacy.ts
    • Modified the description for the content parameter of the write_file tool to explicitly prohibit omission placeholders.
    • Modified the description for the new_string parameter of the replace tool to explicitly prohibit omission placeholders.
  • packages/core/src/tools/definitions/model-family-sets/gemini-3.ts
    • Modified the description for the content parameter of the write_file tool to explicitly prohibit omission placeholders.
    • Modified the description for the new_string parameter of the replace tool to explicitly prohibit omission placeholders.
  • packages/core/src/tools/edit.test.ts
    • Added a test case to reject omission placeholders in new_string when not present in old_string.
    • Added a test case to allow omission placeholders in new_string when the same placeholder is already in old_string.
    • Added a test case to allow normal code containing ellipsis within a string literal.
    • Added a regression test to reject multiline omission placeholder edits that hide unchanged methods.
  • packages/core/src/tools/edit.ts
    • Imported the detectOmissionPlaceholder utility.
    • Implemented validation logic in validateToolParams to check new_string for omission placeholders and reject them unless old_string contains the identical placeholder.
  • packages/core/src/tools/omissionPlaceholderDetector.test.ts
    • Added a new test file to verify the functionality of the detectOmissionPlaceholder utility, covering various placeholder formats and edge cases.
  • packages/core/src/tools/omissionPlaceholderDetector.ts
    • Added a new utility file containing the detectOmissionPlaceholder function and its associated interface, responsible for identifying specific omission placeholder patterns.
  • packages/core/src/tools/write-file.test.ts
    • Added a test case to throw an error if content includes an omission placeholder.
    • Added a test case to allow content with ellipsis in a normal string literal.
    • Added a regression test to reject omission placeholders within multiline file content.
  • packages/core/src/tools/write-file.ts
    • Imported the detectOmissionPlaceholder utility.
    • Implemented validation logic in validateToolParams to check content for omission placeholders and reject them.
Activity
  • A new omissionPlaceholderDetector.ts utility was created to identify specific placeholder patterns.
  • Validation logic was added to edit.ts and write-file.ts to utilize the new detector and prevent unwanted placeholder insertions.
  • Tool descriptions in model-family-sets/gemini-3.ts and model-family-sets/default-legacy.ts were updated to explicitly guide models away from using omission placeholders.
  • New unit and regression tests were added for the detector, EditTool, and WriteFileTool to ensure the fix is robust and covers various scenarios.
  • Snapshot tests for tool definitions were updated to reflect the changes in descriptions.
  • The PR author confirmed that newly added regression assertions failed on the pre-change commit, validating the necessity of this fix, and now pass with the changes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces validation to prevent the model from using omission placeholders like (rest of methods ...) in file edit and write operations, which was causing unintended code deletions. The approach of adding validation guards in replace and write_file, strengthening tool descriptions, and adding regression tests is solid. However, I've identified a critical flaw in the placeholder detection logic for the edit tool that could allow the original bug to persist in certain scenarios. My review includes a detailed explanation and suggestions for a more robust fix.

@gemini-cli gemini-cli bot added the area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality label Feb 22, 2026
@nsalerni nsalerni marked this pull request as ready for review February 22, 2026 01:54
@nsalerni nsalerni requested a review from a team as a code owner February 22, 2026 01:54
@bdmorgan bdmorgan added this pull request to the merge queue Feb 22, 2026
Merged via the queue into google-gemini:main with commit faa1ec3 Feb 22, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AI replaces the 'unchanged code' with "(rest of methods ...)" placeholder on diff-changes

2 participants