Skip to content

Default opencode (server+TUI) corrupts ConPTY-hosted parent shell on exit; shell crashes with NT_STATUS/CLR error code #26480

Closed as not planned

Description

@Zyl0812

Description

Summary

On Windows, exiting opencode in its default server+TUI mode (via /exit or Ctrl+C×2) kills the parent shell when that shell is hosted in a ConPTY (the standard Win32 pseudoconsole used by every modern Windows terminal: Warp, Windows Terminal, VS Code, etc.). The same opencode binary, run from a native conhost.exe window, leaves the parent shell alive. This points at console-handle / FreeConsole cleanup in opencode (or its bun runtime) that is benign against full conhost but corrupts ConPTY's internal state.

The user-visible symptom is that the host terminal's pane closes immediately, because the host terminal correctly reacts to its child shell dying.

This is a more focused diagnosis of the same issue partially addressed in #6189 (closed). #6189 only covered the Ctrl+C key-handler exit path; the bug here reproduces equally on /exit and is not about input handling.

Differential reproduction matrix

Console host opencode mode Parent shell dies?
conhost.exe (classic Windows console window) default (server+TUI) No
ConPTY (Warp / Windows Terminal / VS Code) default
(server+TUI) **Y
ConPTY opencode serve … + opencode attach … No
ConPTY, with `cmYes**
ConPTY, with powershell -NoExit -Command "opencode" default Yes

Three things narrow the cause:

  1. **Console-host ted shells die.Native conhost is fine.
  2. Server-child dependent — opencode attach (no spawned server child) is fine. The trigger is in the cleanup path of the server child opencode forks in default mode.
  3. Shell agnostic — both PowerShell and cmd die. So it isn't PowerShell's .NET Console doing something special; it's something happening to the shared ConPTY console state that any shell will then trip over.

Captured shell exit code (PowerShell case)

I instrumented Warp's Windows PTY callback to call GetExitCodeProcess on the shell handle the moment ChildExitWatcher fires:

ChildExitWatcher: shell process handle signaled, exit_code=0x80131623 (2148734499), sending Message::ChildExited to
event loop

Decoding 0x80131623:

  • bit 31 (severity) = 1 (error)
  • facility = 0x013 = FACILITY_URT (.NET CLR)
  • code = 0x1623, range = .NETSystem.IO / ObjectDisposedException family.

I.e., PowerShell truntime threw anunhandled exception when next accessing the Console** (e.g., Console.In/Console.Out reading from a stream backed by a now-disposed/closed handle). With cmd as the host shell the exact code is presumably different, but the precondition is the same: ConPTY console state has been left in a state that the next console read fails.
This pattern is co

  • The server child or its child processes calling FreeConsole (and/or AttachConsole) on shutdown. Microsoft's own ConPTY documentation explicitly notes that FreeConsole/AttachConsole are not fully suppave thepseudoconsole in an inconsistent state (which is invisible under classic conhost because conhost manages console attachment via kernel objects rather than pipe state).
  • Closing inheritendles in a waythat, in pipe-backed ConPTY, causes the underlying pipe to advance to EOF for everyone — even though the same close is a no-op for other consumers under conhost's reference-counted console-object model.
  • bun runtime fd cleanup ([bun-issues that touch console handles in the past] FYI for cross-reference) treating console handles like ordinary fds and close()-ing them.

What I'd like to learn from the opencode side

Verifying which ither fix itupstream or file a precise bug at bun/Go runtime. Concrete asks:

  1. On Windows, doecode serveprocess when default mode forks it) callFreeConsole, AttachConsole, SetStdHandle, or CloseHandleon any ofSTD_INPUT_HANDLE/STD_OUTPUT_HANDLE/STD_ERROR_HANDLE` during shutdown?
  2. Is the server child created with bInheritHandles = TRUE and the parent's std handles inherited as-is? If so, does the server child later close those handles, even via the runtime's automatic
    fd-on-exit cleanup
  3. Does any teardoGenerateConsoleCtrlEvent(CTRL_C_EVENT, 0) or (CTRL_BREAK_EVENT, 0) against the shared console? (Already partly addressed by In the Windows system, pressing Ctrl+C will automatically exit the terminal #6189, but worth confirming for the /exit path too.)

A minimal mitigation that has worked for similar issues in other projects:

  • Spawn the server child detached, in its own console
    (`CREATE_NEW_CONSOo it can nevershare console handles with the user's interactive shell.
  • Or, before forking the server child, duplicate the std handles into ones the server child owns exclusively (and don't pass through the originals).

Cross-references

Environment

  • OS: Windows 11 Home, build 26200
  • Shell tested: PowerShell 7 (also reproduces in cmd /k opencode and powershell -NoExit -Command "opencode")
  • Console hosts tested: ConPTY (via Warp) reproduces; classic conhost.exe does not
  • opencode version 如 1.0.202>`
  • Repro is 100% de

I'm happy to capture additional traces (Process Monitor, WinDbg post-mortem, etc.) if that helps narrow down the exact API call.

Plugins

No response

OpenCode version

No response

Steps to reproduce

  1. On Windows 11, open a ConPTY-backed terminal — any of: Warp, Windows Terminal, VS Code's integrated terminal.
  2. In the resulting PowerShell 7 (or pwsh) prompt, run:
    opencode
  3. Wait for the OpenCode TUI to load.
  4. Exit OpenCode using either of:
  • Type /exit and press Enter, or
  • Press Ctrl+C twice in quick succession.
  1. Observed: the parent PowerShell process terminates immediately (the host terminal pane closes, because the host correctly reacts to its child shell dying). On Warp the pane vanishes; on Windows Terminal the tab closes; on VS Code the integrated terminal session ends.
  2. Expected: OpenCode exits and control returns to the PowerShell prompt, which is what happens in a native conhost.exe window with the same opencode binary.

Screenshot and/or share link

No response

Operating System

Windows 11

Terminal

Warp

Activity

  1. github-actions commented on May 9, 2026

    @github-actions
    Contributor

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

    If your issue is distinct (e.g., the ConPTY-specific diagnosis or the /exit path not covered by #6189), please clarify how it differs from the above issues so maintainers can track it separately.

  2. github-actions commented on Aug 6, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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