anomalyco / anomalyco/opencode

TUI crashes at startup (Bun SIGILL in drainMicrotasks, libopentui) when the terminal answers the capability handshake only partially

Open
#41,483 1 comment 0 reactions 1 assignee View on GitHub

@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-hook to 0.2.77)

Bun crash report

https://bun.report/1.3.14/Ba10d9b296m/Gz+339/D4664tE+uzP__suwxrCsuwxrCsuwxrCsuwxrCsuwxrCsuwxrCsuwxrCmsvprCi4wtpFusjtpF8s1muF4r338D__msvprCwpthhFA2k1/B4//o02C

Decoded: segfault at 0x7F5256A23FFC, recursive llint_op_call_ignore_resultJSC::MicrotaskQueue::drainImplJSC::VM::drainMicrotasksBun::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:

  1. Answering only OSC 10/11 → still crashed (5/5)
  2. 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 SIGILL on Linux x86_64, but a different trigger (crashes after running a while, not at startup).
  • #20043 — libopentui.so extraction 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.