bug: apply_patch waits for LSPs sequentially causing big multi-file patches to hang #7819

Open
opened 2026-02-16 18:08:22 -05:00 by yindo · 3 comments
Owner

Originally created by @samdickson22 on GitHub (Jan 28, 2026).

Originally assigned to: @rekram1-node on GitHub.

Description

When apply_patch modifies multiple files, it waits for LSP diagnostics sequentially - up to 3 seconds per file. Patching 20 files can block for 60 seconds.

Code

// packages/opencode/src/tool/apply_patch.ts:235-240
for (const change of fileChanges) {
  if (change.type === "delete") continue
  const target = change.movePath ?? change.filePath
  await LSP.touchFile(target, true)  // 3s timeout, sequential!
}

Plugins

n/a

OpenCode version

1.1.39

Steps to reproduce

Run this prompt with a codex model:

Create 20 TypeScript files at the same time using bash:
- test-perf/utils1.ts through test-perf/utils20.ts
- Each exports: export function util1() { return 1 }

Then use the apply_patch tool (not sed, not individual edits) to add "// patched" as line 1 to ALL 20 files in a single patch.

After the patch tool returns, immediately say "PATCH COMPLETE" so I can time it.

watch it hang on ~ Preparing apply_patch... for 60 seconds

Screenshot and/or share link

No response

Operating System

macOS 15.6.1

Terminal

Ghostty

Originally created by @samdickson22 on GitHub (Jan 28, 2026). Originally assigned to: @rekram1-node on GitHub. ### Description When `apply_patch` modifies multiple files, it waits for LSP diagnostics **sequentially** - up to 3 seconds per file. Patching 20 files can block for 60 seconds. ### Code ```typescript // packages/opencode/src/tool/apply_patch.ts:235-240 for (const change of fileChanges) { if (change.type === "delete") continue const target = change.movePath ?? change.filePath await LSP.touchFile(target, true) // 3s timeout, sequential! } ``` ### Plugins n/a ### OpenCode version 1.1.39 ### Steps to reproduce Run this prompt with a codex model: ``` Create 20 TypeScript files at the same time using bash: - test-perf/utils1.ts through test-perf/utils20.ts - Each exports: export function util1() { return 1 } Then use the apply_patch tool (not sed, not individual edits) to add "// patched" as line 1 to ALL 20 files in a single patch. After the patch tool returns, immediately say "PATCH COMPLETE" so I can time it. ``` watch it hang on `~ Preparing apply_patch...` for 60 seconds ### Screenshot and/or share link _No response_ ### Operating System macOS 15.6.1 ### Terminal Ghostty
yindo added the bugperf labels 2026-02-16 18:08:22 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Jan 28, 2026):

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

  • #9102: Agents misinterpret LSP diagnostics as failed edits - Related to how apply_patch waits for LSP diagnostics

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

@github-actions[bot] commented on GitHub (Jan 28, 2026): This issue might be a duplicate of existing issues. Please check: - #9102: Agents misinterpret LSP diagnostics as failed edits - Related to how apply_patch waits for LSP diagnostics Feel free to ignore if none of these address your specific case.
Author
Owner

@rian-dolphin commented on GitHub (Feb 4, 2026):

I'm also seeing hanging for apply_patch but even when I am only editing 1 file. Hangs for many minutes until I eventually interrupt it. I can see that my API request has completed with output tokens by looking in the Zen dashboard (screenshot attached).

Maybe this warrants it's own issue given it's not related to multi-file updates. Though the update was quite a big one based on the number of output tokens.

Image

Also, I interrupted then used /timeline to go back to the prompt and rerun it and the same outcome. Then I interrupted and just told the model to continue, which also resulted in it hanging again. So it seemed like a repeatable issue.

@rian-dolphin commented on GitHub (Feb 4, 2026): I'm also seeing hanging for `apply_patch` but even when I am only editing 1 file. Hangs for many minutes until I eventually interrupt it. I can see that my API request has completed with output tokens by looking in the Zen dashboard (screenshot attached). Maybe this warrants it's own issue given it's not related to multi-file updates. Though the update was quite a big one based on the number of output tokens. <img width="702" height="77" alt="Image" src="https://github.com/user-attachments/assets/8296a596-15f7-4484-986a-aaee0a81da04" /> Also, I interrupted then used /timeline to go back to the prompt and rerun it and the same outcome. Then I interrupted and just told the model to continue, which also resulted in it hanging again. So it seemed like a repeatable issue.
Author
Owner

@rian-dolphin commented on GitHub (Feb 4, 2026):

Okay, so this was a dumb issue on my part (but also a very unclear UX that could be improved). Turns out I had added a directory to my .gitignore between prompts and then when it tried to write to the file that was now gitignored it caused the whole thing to hang indefinitely. Problem resolved when I removed the directory from the gitignore.

Definitely unrelated to this issue but going to leave it here in case anyone happens across it in the future and might find it useful.

@rian-dolphin commented on GitHub (Feb 4, 2026): Okay, so this was a dumb issue on my part (but also a very unclear UX that could be improved). Turns out I had added a directory to my `.gitignore` between prompts and then when it tried to write to the file that was now gitignored it caused the whole thing to hang indefinitely. Problem resolved when I removed the directory from the gitignore. Definitely unrelated to this issue but going to leave it here in case anyone happens across it in the future and might find it useful.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#7819