anomalyco / anomalyco/opencode
TUI crashes at startup (Bun SIGILL in drainMicrotasks, libopentui) when the terminal answers the capability handshake only partially
@simonklee is already working on this.
Since Aug 10, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
The TUI crashes deterministically at startup (Bun panic, SIGILL, inside JSC::VM::drainMicrotasks) when the terminal on the other end answers opencode's startup capability handshake only partially.
Reproduces 100% over the Moshi phone client. The same binary on the same machine starts fine in a local terminal, and — importantly — also starts fine over plain mosh with a locally attached mosh-client. So this is not "mosh" in general; it is terminal emulations that reply to some capability queries but not others.
Characterized over ~40 controlled runs.
Environment
- opencode 1.18.15 (also seen on 1.17.x)
- Bun 1.3.14 (bundled),
Linux x86_64_baseline [StandaloneExecutable] - Arch Linux, kernel 6.18.42-1-lts, glibc 2.42
- Client: Moshi phone app (crash persists after updating both the phone app and
moshi-hookto 0.2.77)
Bun crash report
Decoded: segfault at 0x7F5256A23FFC, recursive llint_op_call_ignore_result → JSC::MicrotaskQueue::drainImpl → JSC::VM::drainMicrotasks → Bun::jsFunctionDrainMicrotaskQueue (BunProcess.cpp:3806).
Coredump
SIGILL, command line opencode .:
#0 0x0000000002607064 (opencode + 0x2407064)
#1 0x0000000002605266 (opencode + 0x2405266)
#2 0x00000000034dd8bf (opencode + 0x32dd8bf)
#3 0x00000000046e35ad (opencode + 0x44e35ad)
#4 0x00007f4e5f83e6f0 (libc.so.6 + 0x3e6f0)
#5 0x00007f4e09c2061d (/tmp/.9adb59f9f3fcffdf-00000000.so + 0x1d061d) <-- libopentui
#6 0x000004305a263a93
#7 0x00007f4e12a0c038
#8 0x00000000025c60e7 (opencode + 0x23c60e7) <-- repeats x7, recursion
...
Frame #5 is the extracted libopentui.so (see #20043 for the /tmp extraction). The offset libopentui.so + 0x1d061d is identical across every crash.
Reproduction matrix
| Terminal on the other end | Answers the handshake | Result |
|---|---|---|
script, no terminal behind it |
nothing | OK |
| real xterm | everything | OK (4/4) |
plain mosh-server + local mosh-client, sized pty |
— | OK (2/2, verified today) |
mosh-server with no client attached |
nothing | OK |
| herdr | everything except OSC 10/11 | CRASH |
| Moshi phone client | partial | CRASH (5/5) |
Nothing answered → clean fallback. Everything answered → works. An incomplete set → crash.
The handshake
Captured with a shim on the pty, opencode sends:
\x1b[?2031h \x1b]10;? \x1b]11;? \x1b[>0q \x1b[6n \x1bP+q4d73 \x1b[?1016$p \x1b[?2027$p
A real xterm replies with ]10;rgb:... and ]11;rgb:.... Moshi and herdr do not.
Two attempted fixes that did NOT work
A pty shim that intercepts the queries and answers them on the terminal's behalf:
- Answering only OSC 10/11 → still crashed (5/5)
- Answering all 7 captured queries and stripping them from the stream → still crashed (4/4)
So "missing replies" describes the symptom but is not the whole cause. Something about the partial interleaving appears to matter.
Ruled out (all still 100% crash)
TUI plugins, directory plugins, all plugins disabled, MCP servers, empty config, terminal width (tested 37 and 200 columns), and 13 combinations of OpenTUI env vars: OPENTUI_NOTIFICATIONS, OPENTUI_NOTIFICATION_PROTOCOL, OPENTUI_IMAGE_PROTOCOL, OPENTUI_GRAPHICS, OPENTUI_FORCE_EXPLICIT_WIDTH, OPENTUI_FORCE_WCWIDTH, OPENTUI_FORCE_NOZWJ, OTUI_NO_NATIVE_RENDER, OTUI_USE_ALTERNATE_SCREEN, OTUI_PALETTE_IDLE_TIMEOUT_MS, TERM=dumb, TERM=vt100, and faking TMUX/ZELLIJ.
A terminal multiplexer in the middle is not required: it crashes over the phone client with nothing in between.
Note on measuring
Count crashes with coredumpctl list | wc -l, not by reading the panel — the previous crash banner stays in the scrollback and produces false positives. Also start a fresh pane per attempt: a pane with a live opencode swallows the next command as keystrokes.
Related
- #35384 — same shape on ARM64: crashes when started from a phone SSH client (Termius), fine locally. Currently has no reproduction details; this report may be the same root cause.
- #33890 — Bun 1.3.14
SIGILLon Linux x86_64, but a different trigger (crashes after running a while, not at startup). - #20043 —
libopentui.soextraction into/tmp, which is the module in frame #5.
Expected
A terminal that answers the capability handshake incompletely should fall back the same way a terminal that answers nothing does, instead of taking down the process.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.