anomalyco / anomalyco/opencode
[Bug]: TUI does not render externally injected (steer) turns or the assistant's reply while attached — data intact in DB (v1.18.26)
@kommander is already working on this.
Since Sep 6, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- Avg merge
- 7h 2m
- Merged PRs (30d)
- 384
Description
Description
While the TUI is attached, turns injected externally (steer) into an idle session — in this case a <system-reminder> user message delivered when a background subagent completes — and the assistant's reply to them are not rendered in the TUI. The conversation view jumps from the last locally-typed message straight to the next locally-typed message. Locally-typed turns render normally.
The data layer is fully intact: both the injected user turn and the assistant reply are persisted in the DB with correct content and no hiding flags, and the server log shows the wake-up run executed cleanly (INFO only, no errors).
This is a fresh, cleanly-evidenced instance of the symptom class from #41289 (closed by the reporter as "less consistent than reported" — see also #8564, #26671, candidate fix PR #26936 which was never confirmed). Reproduced twice in a row on v1.18.26.
Plugins
oh-my-opencode (omo). The injection is performed by omo's background-task completion notification (same steer/prompt_async path as #41289's pure-HTTP repro). Note the rendering gap itself is in the TUI's handling of externally injected turns, independent of which client performs the injection — #41289 reproduced it with plain curl.
OpenCode version
v1.18.26 (homebrew, current latest stable)
Steps to reproduce
- Open the TUI in a session, let it go idle (agent finished its turn).
- Have the agent launch a background subagent that completes a few seconds later (omo
task(..., run_in_background=true)). - The plugin injects a
<system-reminder>user message into the parent session via steer; the server wakes the session, the model replies (verified in DB). - Watch the TUI while 2–3 run: neither the injected turn nor the assistant's reply appears. The view stays on the last locally-typed exchange.
- Type any message locally: it and its reply render normally, after the invisible gap.
Evidence (all timestamps UTC, session ses_f89f80d79ffejhqzqNImj9GU2w):
Timeline (from ~/.local/share/opencode/log/opencode.log and opencode.db):
| Time | Event |
|---|---|
| 09:27:02.893 | child session created (explore subagent, parentID = this session) |
| 09:27:02.905 | child replies (PONG-2) |
| 09:27:08 | reminder #1 persisted as user msg msg_0760b02ab001c5AXKMgrmSbCxq |
| 09:27:10.538 | reminder #2 (identical duplicate) persisted as user msg msg_0760b0bca0019uwqYxxrHUya98 |
| 09:27:10.543 | wake-up run starts (run=50a553ac, distinct from the interactive run) |
| 09:27:10.545 | assistant msg msg_0760b0bd1001rQIda5zOKKXHMq created (parent = reminder #2), contains the text reply to the notification |
| 09:27:16 / 09:27:22 | follow-up assistant msgs (tool calls + final summary) |
| 09:27:27.839 | run exits loop normally |
Log excerpt (wake-up run, INFO only throughout):
timestamp=2026-09-06T09:27:10.543Z level=INFO run=50a553ac message=loop session.id=ses_f89f80d79ffejhqzqNImj9GU2w step=0
timestamp=2026-09-06T09:27:10.564Z level=INFO run=50a553ac message=process session.id=ses_f89f80d79ffejhqzqNImj9GU2w messageID=msg_0760b0bd1001rQIda5zOKKXHMq
timestamp=2026-09-06T09:27:10.565Z level=INFO run=50a553ac message=stream providerID=zhipuai-coding-plan modelID=glm-5.3 ...
timestamp=2026-09-06T09:27:27.839Z level=INFO run=50a553ac message="exiting loop" session.id=ses_f89f80d79ffejhqzqNImj9GU2w step=3
DB proof (sqlite, message + part tables):
-- both injected reminders persisted, with full text:
msg_0760b02ab001c5AXKMgrmSbCxq | {"type":"text","text":"<system-reminder>\n[BACKGROUND TASK COMPLETED]\n[ALL BACKGROUND TASKS COMPLETE]\n\n**Completed:**\n- `bg_3f428c9d`: Notificatio…
msg_0760b0bca0019uwqYxxrHUya98 | (identical duplicate, 2.4s later)
-- the invisible assistant reply persisted, normal flags, no synthetic/ignored:
msg_0760b0bd1001rQIda5zOKKXHMq | {"type":"text","text":"📢 **显式确认:我已收到后台任务完成通知。**\n\n- 收到时间:…
-- message row: role=assistant, parentID=msg_0760b0bca…, finish/tool-calls, tokens counted
Neither message carries synthetic or ignored flags, so this is not the flag-based skip — the TUI simply never rendered these turns while attached.
Two additional observations from the same repro that may complicate the render path:
- Duplicate injection: the reminder was injected twice (two persisted user messages 2.4s apart). In an earlier round of the same test the reminder was not persisted at all (assistant wake-up reply exists at 09:24:13 with no preceding user row) — persistence on this path is inconsistent.
- A background-notification wake during an active parent turn is a separate known timing class (see omo repo issues); this report is strictly about the attached-TUI rendering gap.
Screenshot and/or share link
Available on request (contains a private session; happy to share/redact). DB message IDs above are verbatim for correlation.
Operating System
macOS 26.5 (arm64)
Terminal
ghostty 1.x, direct attach (no tmux/zellij), TERM=xterm-256color
Expected behavior
Injected turns and the assistant's reply render in the attached TUI live (or on the next event batch), exactly like locally-typed turns. At minimum, a re-render/backfill should cover them; per #41289's reporter, a freshly attached TUI does render the assistant reply, but the injected user turn still never appears — suggesting the TUI depends entirely on live SSE delivery for these turns with no hydration fallback.
Actual behavior
The injected user turn and the assistant's reply never render while attached; the human user only discovers the gap when comparing the DB/API against the screen. Messages typed locally before/after render fine.
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.