bug: ctrl+c exiting app even when prompt input isn't empty #3304

Closed
opened 2026-02-16 17:39:35 -05:00 by yindo · 13 comments
Owner

Originally created by @rekram1-node on GitHub (Dec 4, 2025).

Originally assigned to: @kommander on GitHub.

Description

see screen recording:
https://discord.com/channels/1391832426048651334/1394667004979445931/1446206223396634715

OpenCode version

1.0.132

Operating System

Windows

Terminal

Windows Terminal

Originally created by @rekram1-node on GitHub (Dec 4, 2025). Originally assigned to: @kommander on GitHub. ### Description see screen recording: https://discord.com/channels/1391832426048651334/1394667004979445931/1446206223396634715 ### OpenCode version 1.0.132 ### Operating System Windows ### Terminal Windows Terminal
yindo added the windowshelp-wantedopentuibug labels 2026-02-16 17:39:35 -05:00
yindo closed this issue 2026-02-16 17:39:35 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Dec 4, 2025):

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

  • #2999: Provide means to disable Ctrl-C (Windows users unable to use Ctrl+C without crashing)
  • #4997: Keybinds (explicitly lists: 'Windows ctrl+c quits app instead of copy')
  • #5070: exiting tui on windows has improper exit sequence handling (similar Windows terminal symptoms)
  • #3675: Keybind doesn't work in 1.0.7 (Windows 11, Windows Terminal - custom keybinds not working)
  • #4938: Keyboard shortcuts to edit prompts suck so much! (comprehensive keyboard/input issues)
  • #3213: Bug: opencode run and TUI exits hang on v0.15+ (Ctrl+C doesn't return shell prompt on Windows)

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

@github-actions[bot] commented on GitHub (Dec 4, 2025): This issue might be a duplicate of existing issues. Please check: - #2999: Provide means to disable Ctrl-C (Windows users unable to use Ctrl+C without crashing) - #4997: Keybinds (explicitly lists: 'Windows ctrl+c quits app instead of copy') - #5070: exiting tui on windows has improper exit sequence handling (similar Windows terminal symptoms) - #3675: Keybind doesn't work in 1.0.7 (Windows 11, Windows Terminal - custom keybinds not working) - #4938: Keyboard shortcuts to edit prompts suck so much! (comprehensive keyboard/input issues) - #3213: Bug: `opencode run` and TUI exits hang on v0.15+ (Ctrl+C doesn't return shell prompt on Windows) Feel free to ignore if none of these address your specific case.
Author
Owner

@val-2 commented on GitHub (Dec 7, 2025):

Hi! I’d like to work on this issue if it’s still available.
I'm able to reproduce the issue on Windows Terminal on both last release version and last commit version.

@val-2 commented on GitHub (Dec 7, 2025): Hi! I’d like to work on this issue if it’s still available. I'm able to reproduce the issue on Windows Terminal on both last release version and last commit version.
Author
Owner

@rekram1-node commented on GitHub (Dec 7, 2025):

@val-2 that'd be great, note that opencode is built on opentui, so you may find that the bug lies at that lower level.

@rekram1-node commented on GitHub (Dec 7, 2025): @val-2 that'd be great, note that opencode is built on [opentui](https://github.com/sst/opentui), so you may find that the bug lies at that lower level.
Author
Owner

@val-2 commented on GitHub (Dec 7, 2025):

Ok I think I found the issue but I'm not exactly sure how to resolve it.

Basically the bug starts manifesting when client.call("checkUpgrade",...) gets called, which happens 1 second after start.
I think the commands that get called for the check in some way "steal" ctrl-c handling of opencode and thus the normal exit path doesn't get followed but it just exits without clean-up. Might be partially related to #5070 as well.
So the reason why the bug happened in the video is not the start of the request but the start of checkUpgrade.
If I remove the checkUpgrade call the bug doesn't happen anymore.

Another thing I noticed is that the commands modify the name of the terminal tab when they get called, so it becomes "npm list", "npm config get registry"...

A possible fix I found is to use Bun.spawn instead of Bun shell $, for example:

$`npm list -g --depth=0`

becomes

Bun.spawn(["npm", "list", "-g", "--depth=0"])

With all the relative adjustments to get stdout and such.

I don't know enough about Bun internals to tell why this fixes the bug though. Or if it's more of a Bun issue than an OpenCode one.

Let me know if you'd like me to open a PR for the change or if you prefer a different approach.

@val-2 commented on GitHub (Dec 7, 2025): Ok I think I found the issue but I'm not exactly sure how to resolve it. Basically the bug starts manifesting when `client.call("checkUpgrade",...)` gets called, which happens 1 second after start. I think the commands that get called for the check in some way "steal" ctrl-c handling of opencode and thus the normal exit path doesn't get followed but it just exits without clean-up. Might be partially related to #5070 as well. So the reason why the bug happened in the video is not the start of the request but the start of checkUpgrade. If I remove the checkUpgrade call the bug doesn't happen anymore. Another thing I noticed is that the commands modify the name of the terminal tab when they get called, so it becomes "npm list", "npm config get registry"... A possible fix I found is to use Bun.spawn instead of Bun shell $, for example: ```typescript $`npm list -g --depth=0` ``` becomes ```typescript Bun.spawn(["npm", "list", "-g", "--depth=0"]) ``` With all the relative adjustments to get stdout and such. I don't know enough about Bun internals to tell why this fixes the bug though. Or if it's more of a Bun issue than an OpenCode one. Let me know if you'd like me to open a PR for the change or if you prefer a different approach.
Author
Owner

@val-2 commented on GitHub (Dec 15, 2025):

Hi @rekram1-node, quick ping. Should I open a PR with this fix or try a different approach? Thanks!

@val-2 commented on GitHub (Dec 15, 2025): Hi @rekram1-node, quick ping. Should I open a PR with this fix or try a different approach? Thanks!
Author
Owner

@rekram1-node commented on GitHub (Dec 15, 2025):

@val-2 so if you disable checkUpgrade the issue doesn't happen but if you enable it it does?

@rekram1-node commented on GitHub (Dec 15, 2025): @val-2 so if you disable checkUpgrade the issue doesn't happen but if you enable it it does?
Author
Owner

@val-2 commented on GitHub (Dec 15, 2025):

Yes exactly, in general it seems to start happening when an "npm" command is launched with Bun.$
The bug stops happening when Bun.spawn or Bun.syncSpawn is used
Here is a video showing it

https://github.com/user-attachments/assets/efd1e2ed-74d3-482a-a5b1-df8f41f5c501

https://github.com/user-attachments/assets/fe7ca136-36bf-4a20-89b6-a205100b80c0

@val-2 commented on GitHub (Dec 15, 2025): Yes exactly, in general it seems to start happening when an "npm" command is launched with Bun.$ The bug stops happening when Bun.spawn or Bun.syncSpawn is used Here is a video showing it https://github.com/user-attachments/assets/efd1e2ed-74d3-482a-a5b1-df8f41f5c501 https://github.com/user-attachments/assets/fe7ca136-36bf-4a20-89b6-a205100b80c0
Author
Owner

@val-2 commented on GitHub (Dec 15, 2025):

Also it seems to happen in particular with npm commands. If I replace $`npm config get registry`.text() with $`bun pm ls -g`.text() in the code in the second video, OpenCode exits correctly

@val-2 commented on GitHub (Dec 15, 2025): Also it seems to happen in particular with npm commands. If I replace ```$`npm config get registry`.text()``` with ```$`bun pm ls -g`.text()``` in the code in the second video, OpenCode exits correctly
Author
Owner

@rekram1-node commented on GitHub (Dec 15, 2025):

Ohh interesting, yeah @val-2 go ahead w/ a PR thanks!

@rekram1-node commented on GitHub (Dec 15, 2025): Ohh interesting, yeah @val-2 go ahead w/ a PR thanks!
Author
Owner

@kommander commented on GitHub (Dec 20, 2025):

This is a bun issue that is reported and being worked on where it doesn't handle the windows CTRL_C_EVENT signal, so the signal cannot be intercepted and the process is immediately shut down.

@kommander commented on GitHub (Dec 20, 2025): This is a bun issue that is reported and being worked on where it doesn't handle the windows `CTRL_C_EVENT` signal, so the signal cannot be intercepted and the process is immediately shut down.
Author
Owner

@aiyolo commented on GitHub (Dec 26, 2025):

watching

@aiyolo commented on GitHub (Dec 26, 2025): watching
Author
Owner

@val-2 commented on GitHub (Jan 4, 2026):

I tested on last commit and the bug on Windows still appears on the last Bun version. I had already tried experimenting with .quiet() and .nothrow() but it didn't work, also per Bun docs ".text() automatically calls .quiet()".

I also tried to find some other fixes, like re-enabling raw mode after npm commands finished running or using process.on("SIGINT", ...) to call the normal exit path, but I didn't find anything else that worked as a workaround while waiting for the fix in Bun, other than the method I sent earlier.

@val-2 commented on GitHub (Jan 4, 2026): I tested on last commit and the bug on Windows still appears on the last Bun version. I had already tried experimenting with `.quiet()` and `.nothrow()` but it didn't work, also per Bun docs ".text() automatically calls .quiet()". I also tried to find some other fixes, like re-enabling raw mode after npm commands finished running or using process.on("SIGINT", ...) to call the normal exit path, but I didn't find anything else that worked as a workaround while waiting for the fix in Bun, other than the method I sent earlier.
Author
Owner

@val-2 commented on GitHub (Jan 4, 2026):

Also since it may be useful for the bugfix upstream, by testing on a separate project it appears '\x03' handling with rawMode works correctly with Bun on Windows in normal conditions and breaks only after invoking npm/pnpm/yarn via Bun.$. The same issue occurs when using Bun.spawn with stdin: "inherit", but not with stdin: "ignore", so the bug might lie in inheritance and modification of the current TTY state.

@val-2 commented on GitHub (Jan 4, 2026): Also since it may be useful for the bugfix upstream, by testing on a separate project it appears '\x03' handling with rawMode works correctly with Bun on Windows in normal conditions and breaks only after invoking npm/pnpm/yarn via Bun.$. The same issue occurs when using Bun.spawn with stdin: "inherit", but not with stdin: "ignore", so the bug might lie in inheritance and modification of the current TTY state.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#3304