Skip to content

Edits often corrupt files and agents have to restart all work #2540

Closed

Description

@divmgl

Happens with both Sonnet and Kimi K2. I'm unsure why this tends to happen, but the agents will often incorrectly edit files using Opencode's tools. I suspect there's a subtle bug in the replacing of text but I haven't been able to narrow it down. At first I thought it was only Kimi K2 but now it's happening with Claude as well. Makes OpenCode unusable.

Also want to highlight all of the other annoyances pointed out, like #2324 and #2536 which continue to pollute and destroy the context.

Another but is that cancelling does not work right away. Seems like this error has come back: #888

Activity

  1. github-actions commented on Sep 10, 2025

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    Feel free to ignore if none of these address your specific case.

  2. remorses commented on Sep 11, 2025

    @remorses
    Contributor

    Very likely related to #2433

    Fixed by #2534

  3. Shinobu-Kazahana commented on Sep 12, 2025

    @Shinobu-Kazahana

    This is not fixed. cannot use the tool at all, every single edit tool call fails with "old string.." error. editing fails, and massive corruption. on latest update. using gemini 2.5 pro, was working fine on version from 3 days prior to this comment.

  4. rekram1-node commented on Dec 28, 2025

    @rekram1-node
    Contributor

    [automated] Closing due to 90+ days of inactivity. Feel free to reopen if you still need this!

  5. WZQ66 commented on Mar 29, 2026

    @WZQ66

    I've just developed (with AI) a plugin that bans the edit tool.
    See https://noedit.qmiweb.com/

  6. ChaoJia commented on Jun 6, 2026

    @ChaoJia

    In case someone else still has this issue like me, gemma4 suggested me to add this skill to opencode, seems to work so far:

    ---
    name: precise-edit
    description: Use ONLY when performing file edits to ensure maximum reliability and minimum token waste.
    ---
    
    # Precise Edit Workflow
    
    To avoid "corrupt patch" errors, "off-by-one" line number failures, or the token waste of full-file rewrites, always follow this strict workflow when modifying code:
    
    ## The Workflow
    
    1. **Read**: Use the `read` tool to get the most current version of the file.
    2. **Extract**: Identify the exact, byte-for-byte string that needs to be replaced. This includes all indentation (tabs/spaces) and newlines.
    3. **Edit**: Use the `edit` tool with the exact string as `oldString`.
        - **NEVER** guess line numbers.
        - **NEVER** assume the content of the file based on previous turns.
        - **NEVER** provide a "shorthand" or "roughly correct" string.
    4. **Verify**: Run a compile check (e.g., `cargo check`, `npm run typecheck`) immediately after the edit.
    
    ## Why this is preferred
    - **Reliability**: Using the exact string from a fresh `read` ensures the `edit` tool finds the match.
    - **Token Efficiency**: It avoids the massive token cost of a full-file `write`.
    - **Safety**: It prevents "corrupt patch" errors associated with manual diff construction.
    
    ## Examples
    
    **Incorrect (Guessing):**
    `edit(filePath="src/main.rs", oldString="fn main() {", newString="fn main() {\n    println!(\"hello\");")` $\rightarrow$ High risk of failure if indentation differs.
    
    **Correct (Precise):**
    1. `read(filePath="src/main.rs")` $\rightarrow$ sees `"12: fn main() {"`
    2. `edit(filePath="src/main.rs", oldString="fn main() {", newString="fn main() {\n    println!(\"hello\");")` $\rightarrow$ Guaranteed success.

    Edit:
    you can also ask the LLM about how to improve the skill whenever the edit fails or causes another compile failure. For me it added the following to the workflow:

        - **CRITICAL**: If an `edit` fails, you MUST call `read` again to synchronize with the current file state before retrying. **NEVER** use the `write` tool as a fallback for a failed `edit`.
        - **Scope Check**: When replacing a block of code, explicitly identify all variables defined within that block. Ensure they are either preserved or redefined in the `newString` to avoid scope errors.
        - **Atomic Logic**: Ensure the `newString` is a self-contained logic unit that does not rely on variables deleted during the replacement.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions