Repository navigation
Description
Description
The file modification tools (edit, write, apply_patch) and shell tool lack fundamental data-loss prevention guards. AI agents can silently overwrite files, replace unintended content, or delete project files without adequate safeguards. Unlike V2 core tools (which have partial protection like writeIfUnchanged and TargetExistsError), the V1 tools lack these entirely.
Data-Loss Risks by Tool
1. edit.ts (V1) — packages/opencode/src/tool/edit.ts
| # | Risk | Lines | Details |
|---|---|---|---|
| A | replaceAll: true + short oldString → unintended replacements |
714–715 | No minimum-length or uniqueness validation. String like "a" or "const" with replaceAll: true silently replaces every occurrence |
| B | "oldString not found" error doesn't tell AI to re-read | 725 | Message: "It must match exactly, including whitespace, indentation, and line endings" — encourages retry guessing instead of re-reading |
| C | "multiple matches" error doesn't tell AI to re-read | 728 | Message: "Provide more surrounding context to make the match unique" — doesn't suggest re-reading |
| D | No stale-content guard between read (L126) and write (L155) | 126→155 | File changed by another agent/user between read and write is silently overwritten. V2 core already has writeIfUnchanged (file-mutation.ts:143-156) |
2. write.ts (V1) — packages/opencode/src/tool/write.ts
| # | Risk | Lines | Details |
|---|---|---|---|
| E | Unconditionally overwrites existing files | 64 | yield* fs.writeWithDirs(filepath, ...) — no stale-content check, no abort on existing file |
| F | No content validation before writing | entire tool | Can write empty or truncated content |
3. shell.ts (V1) — packages/opencode/src/tool/shell.ts
| # | Risk | Lines | Details |
|---|---|---|---|
| G | rm/del/rmdir inside project not flagged specially |
410 | containsPath check skips extra permissions for project-internal paths. Destructive commands on project files get same treatment as cat or ls |
| H | No git awareness | entire tool | Cannot distinguish tracked vs untracked files; no recovery path for accidental deletion |
4. apply_patch.ts (V1) — packages/opencode/src/tool/apply_patch.ts
| # | Risk | Lines | Details |
|---|---|---|---|
| I | No stale-content check for update hunks | 115→231 | File read at start, written after all hunks processed — stale content overwritten |
| J | "add" hunks don't check if file already exists → silent overwrite | 226 | No TargetExistsError check (unlike V2 core at file-mutation.ts:134-136) |
| K | "delete" hunks remove files with generic permission only | 247 | No additional confirmation for destructive deletion |
5. All V1 tools
| # | Risk | Details |
|---|---|---|
| L | No git integration | Cannot snapshot/restore files before modification. No post-hoc recovery |
Contrast with V2 Core
The V2 core tools already implement some protections that V1 lacks:
writeIfUnchanged(file-mutation.ts:143-156): Compares current file content with read snapshot; returnsStaleContentErrorif modifiedfiles.create()with"wx"flag (file-mutation.ts:123-141): Fails withTargetExistsErrorif file already existsedit.ts(core V2, L114–116): Error message says "File changed after permission approval. Read it again before editing."
These patterns should be applied to V1 tools.
Expected Behavior
- edit tool should validate that oldString is specific enough before allowing
replaceAll - Error messages for "not found" and "multiple matches" should tell the AI to re-read the file
- write tool should warn or abort when overwriting existing files
- shell tool should flag destructive commands (
rm,del,rmdir) with additional warning - apply_patch tool should check file existence before "add" hunks and validate stale content before "update" hunks
- V1 tools should adopt the V2 core patterns (
writeIfUnchanged,TargetExistsError) where applicable
Suggested Fix
This is a cross-cutting concern. The canonical fix is to adopt the V2 core's FileMutation service in V1 tools, which already implements stale-content detection and existence checks. The V1 tools at packages/opencode/src/tool/edit.ts, write.ts, apply_patch.ts should be migrated to use @opencode-ai/core/filesystem/file-mutation where possible, and the error messages in edit.ts should be updated to recommend re-reading.
Activity
github-actions commentedon Jun 7, 2026
This issue might be a duplicate of existing issues. Please check:
If you believe these issues are distinct, please clarify how this issue differs from #30376 and #30864 in particular.