You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug: ctrl+c exiting app even when prompt input isn't empty #5071
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.
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.
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
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
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.
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.
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.
Activity
github-actions commentedon Dec 4, 2025
This issue might be a duplicate of existing issues. Please check:
opencode runand TUI exits hang on v0.15+ #3213: Bug:opencode runand 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.
val-2 commentedon 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.
rekram1-node commentedon 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.
val-2 commentedon 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:
becomes
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 commentedon Dec 15, 2025
Hi @rekram1-node, quick ping. Should I open a PR with this fix or try a different approach? Thanks!
rekram1-node commentedon Dec 15, 2025
@val-2 so if you disable checkUpgrade the issue doesn't happen but if you enable it it does?
val-2 commentedon 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
20251215_231543.mp4
20251215_233245.mp4
val-2 commentedon 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 correctlyrekram1-node commentedon Dec 15, 2025
Ohh interesting, yeah @val-2 go ahead w/ a PR thanks!
kommander commentedon Dec 20, 2025
This is a bun issue that is reported and being worked on where it doesn't handle the windows
CTRL_C_EVENTsignal, so the signal cannot be intercepted and the process is immediately shut down.aiyolo commentedon Dec 26, 2025
watching
val-2 commentedon Jan 5, 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 commentedon Jan 5, 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.