Skip to content

V2: esc interrupt broken #42960

Open
Open

Description

@Genuineh

Description

When using the CLI, the Esc interrupt does not work properly. After exiting with Ctrl+C and reopening opencode2 to resume the previous session, I found that the earlier task is still running in the background.

Plugins

No response

OpenCode version

opencode2 vlocal

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

7.0.5-arch1 x86_64 GNU/Linux

Terminal

kitty

Activity

  1. github-actions commented on Aug 17, 2026

    @github-actions
    Contributor

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

    For keybind-related issues, please also check our pinned keybinds documentation: #4997

  2. changed the title [-]V2: interrupt not work[/-] [+]V2: esc interrupt broken[/+] on Aug 17, 2026
  3. mynameistito commented on Sep 6, 2026

    @mynameistito
    Contributor

    I’m seeing the same underlying behavior on the current Windows beta:

    • opencode2: v0.0.0-beta-19157
    • OS: Windows 11, build 26200
    • Active plugins: none configured

    Reproduction:

    1. Run opencode2 <directory> and start a task that is still running.
    2. Close or exit the TUI before the task finishes, without deliberately passing --continue or --session.
    3. Reopen opencode2 in the same directory.

    The original task is still alive in the shared background service and appears to continue when the client is reopened. In other words, closing the TUI does not reliably stop the active model run or its tool execution. This is especially surprising because a normal opencode2 <directory> launch should not silently behave like an explicit session continuation.

    Expected behavior: exiting the TUI should interrupt/cancel an active run, or OpenCode should clearly indicate that the run was detached and offer an explicit choice to resume it. A deliberate resume should require --continue, --session, or a clear prompt.

    The practical impact is that model requests and file-changing tools can continue after the terminal window has been closed, with no visible client attached. This also makes it difficult to tell whether reopening OpenCode created a new session or reconnected to the old in-flight one.

    This seems related to the Esc-interrupt problem reported here, but the specific issue for me is that closing and reopening the opencode2 CLI leaves the previous run active in the background.

  4. NoirVoider commented on Sep 14, 2026

    @NoirVoider

    +1 related report on opencode2 v2.0.3 (macOS 27.0, arm64): pressing Esc does register, but it takes roughly 1–2 seconds for the running turn to actually stop, so the interrupt feels noticeably laggy. This may be the same user-visible family as the dropped-keypress issue that #48607 addresses (focus guard), though I can't confirm the root cause from the client side. Happy to test a build with #48607 applied and report whether the delay persists.

  5. NoirVoider commented on Sep 17, 2026

    @NoirVoider

    Follow-up and correction to my comment above — I found the root cause, and it is not opencode.

    I previously guessed the delay might be the same family as the input.focused guard in #48607. That was wrong. Same opencode2 build, same session, same terminal — only one thing changed:

    Environment

    • opencode2 v2.0.3
    • macOS 27.0 (build 26A428), arm64
    • Ghostty
    • zsh with microsoft/inshellisense 0.0.4 (Homebrew) sourced from .zshrc

    Behavior

    • With inshellisense loaded: pressing Esc does register, but it takes roughly 1–2 s before the running turn actually stops, so the interrupt feels unresponsive / laggy.
    • With the inshellisense init line commented out in .zshrc: Esc interrupts instantly — same build, same session, same terminal, nothing else changed.

    The line in question:

    # [[ -f "$HOME/.local/share/inshellisense/init/zsh/init.zsh" ]] && source "$HOME/.local/share/inshellisense/init/zsh/init.zsh"

    So the latency is introduced by the shell-level key interceptor that wraps the terminal, not by opencode's interrupt path. That is also why removing the focus guard in #48607 does not address this particular delay: the key is not being dropped, it is being delayed before opencode ever sees it.

    If anyone else finds Esc (or keys in general) sluggish in the TUI, please rule this out first: check whether a shell wrapper such as inshellisense — or another zsh autocomplete plugin that owns keybindings — is active, and try disabling it before digging into the TUI.

    inshellisense has related precedent for TUI conflicts: microsoft/inshellisense#411 (lazygit/lazydocker layout broken inside an is session) and microsoft/inshellisense#418 (Up/Down arrows stolen from shell history). I have filed the TUI-latency report there as well: microsoft/inshellisense#480.

    Maintainers: a one-line Troubleshooting entry ("if Esc/keys feel laggy, rule out shell wrappers like inshellisense") would likely save other users this exact rabbit hole.

  6. Genuineh commented on Sep 17, 2026

    @Genuineh
    Author

    Esc work well on the version of 'opencode2 v0.0.0-beta-19271'

  7. amcique commented on Sep 26, 2026

    @amcique

    oh my god its still broken in 2.0.18 lmfao

  8. amcique commented on Sep 29, 2026

    @amcique

    2.0.19 and still not fixed.

  9. amcique commented on Oct 2, 2026

    @amcique

    Seems like this is an issue only in terminal multiplexers.

  10. yassine-safraoui commented on Oct 20, 2026

    @yassine-safraoui

    Confirming this on v2.1.0 (Windows 10.0.26100 x64, Windows Terminal, PowerShell over cmd.exe, no plugins).

    Repro:

    1. Start a response that keeps running.
    2. Revert a message from the message actions menu while it is still generating. On 2.1.0 this puts the message text back into the prompt but does not revert (server returns session busy), so the turn keeps running.
    3. Press Escape repeatedly to stop the turn. Nothing happens: no esc again to interrupt hint, no interruption, even with several presses. The turn kept running. The machine/terminal was under heavy load at the time.

    A likely cause is in packages/tui/src/component/prompt/index.tsx (session.interrupt):

    if (auto()?.visible) return
    if (!input.focused) return
    ...
    setStore("interrupt", store.interrupt + 1)
    ...
    if (store.interrupt >= 2) ...

    The !input.focused guard returns before the press is counted, so whenever focus is not on the prompt input, every Escape is silently dropped and the footer never shows the armed hint. PR #48607 ("allow interrupting running session regardless of prompt focus") removed exactly this guard, but it was closed because it targeted V1 and no V2 port was made.

    Two things make that guard easy to hit:

    • packages/tui/src/ui/dialog.tsx restores focus after a dialog closes with setTimeout(..., 1), so Escape presses right after closing the message actions dialog land while the prompt is still unfocused.
    • packages/tui/src/routes/session/index.tsx has a priority: 10 layer binding escape,ctrl+c to close the sidebar when it is open on a narrow terminal (TUI: sidebar keymap layer hijacks escape/ctrl+c on narrow terminals #56149), which consumes Escape before session.interrupt sees it.

    Separately, session.interrupt is called with resume: true; if a steer is pending, the run resumes immediately, which can look like the interrupt was ignored.

    So the two-press window itself (5s) does not look like the problem here: the first press is often never counted.

  11. badgerkin commented on Oct 21, 2026

    @badgerkin

    For opencode v2.1.1 TUI running under tmux on Linux, I find that I have to set set-option -g escape-time 10 in my ~/.tmux.conf for opencode to reliably register Esc interrupts.

    My reproducer for an unresponsive agent is to configure a model model who's inference backend is down. Send a one message which stalls trying to reconnect, then queue another. A keyboard Esc is not always registered, and you need four to interrupt the stalled query.

    Given the importance of being able to interrupt agents (stalled or runaway). I humbly request adding an alternative keybind for session_interrupt in the default config, one which is less likely to conflict with terminal environments, like "session_interrupt": "ctrl+\\".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions