Repository navigation
Description
NVDA cannot read streaming assistant replies or counter numbers (desktop app)
Environment
- App: opencode desktop app v1.18.15 (Windows 10/11 x64)
- Screen reader: NVDA (browse mode)
- Renderer: Electron
Problem 1 — Streaming assistant replies are invisible to NVDA
While the assistant is generating a reply, NVDA in browse mode cannot read the new content with the virtual cursor (arrow keys). Pressing Tab once "refreshes" the page and only then the reply becomes readable. The new content is effectively missing from the accessibility tree until the turn finishes.
Root cause (message timeline):
MessageTimelinerenders rows through a virtualized list (createVirtualizer/VirtualTimelineRow), so only viewport rows are in the DOM.- In
renderTimelineRow, theAssistantPartbranch setsaria-hidden=trueon the whole assistant content while the turn is "working":During streaming the entire reply is hidden from assistive tech; it only reappears (and NVDA only notices) after the turn ends.const workingTurn = (userMessageID) => sessionStatus().type !== "idle" && activeMessageID() === userMessageID; // ... createRenderEffect(() => setAttribute(_el, "aria-hidden", workingTurn(assistantPartRow().userMessageID)) );
Verified locally: removing the aria-hidden binding keeps the streaming content in the accessibility tree and NVDA reads it as it grows.
Problem 2 — Counter numbers are read as a long digit string
The context summary (N read / N search / N list via AnimatedCountList) and the todo progress (X of Y todos completed via SessionTodoDock) use the AnimatedNumber component. NVDA reads something like 0123456789... instead of the actual number.
Root cause:
AnimatedNumberrenders each digit as a vertical strip of 30 cells (data-slot=animated-number-cell, digits 0-9 repeated), with only one visible via CSS transform. The hidden cells have noaria-hidden, so their text is exposed to the accessibility tree.- The outer element is a bare
<span data-component=animated-number>that setsaria-labeldynamically, butaria-labelon a roleless<span>is invalid ARIA (axereportsaria-prohibited-attr), so it is not a reliable accessible name.
Verified locally: adding aria-hidden=true to <span data-slot=animated-number-value> (hiding the strip) makes NVDA read the number correctly.
Local workaround (validated)
Patching the two spots above in the desktop app bundle fixes both problems, confirming the root causes.
Suggested upstream fixes
- Streaming replies: do not
aria-hiddenthe assistant content while streaming. Announce new content via a proper live region (role=status/aria-live=polite, with debounce), and consider exposing the virtualized list so screen-reader users can reach off-screen/new rows (higher overscan or a non-virtualized fallback,aria-busyon the scroll container). - Numbers: hide the animated digit strip from assistive tech (
aria-hidden=trueondata-slot=animated-number-value/ the strip) and expose the value as real text or via a valid accessible name (a visually-hidden text node, or an element/role that supportsaria-label).
Activity
github-actions commentedon Aug 9, 2026
This issue might be a duplicate of an existing issue. Please check:
aria-hidden={workingTurn(...)}, reported with NVDA on Windows. Your Problem 1 describes the identical issue.Problem 2 (AnimatedNumber digit strips exposed to assistive tech) appears to be new and not covered by existing issues.
aimansour commentedon Sep 12, 2026
@fire0220, #48597 fixes Problem 1 by keeping the in-progress assistant subtree in the accessibility tree, with regression coverage against a busy/incomplete response. It intentionally does not close this issue because the AnimatedNumber problem still remains. If you can verify the streaming fix with NVDA, please report back and leave a 👍 or ❤️ on the PR if it resolves that part; positive reactions are used by the repository cleanup job.
thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊
aimansour commentedon Oct 12, 2026
Both problems remain relevant to V2, so they now have separate current-version tracking issues:
aria-hidden: bug(session-ui): V2 still hides streaming assistant content from screen readers #54652, addressed by existing PR fix(session-ui): expose streaming assistant steps #51084.Audited latest
v2@4617210822bdbb31e5749751afbfb4584ccedac8; the affected renderer, number component and CSS are unchanged on currentdev. PR #51084 does not fix AnimatedNumber. These V2 issues continue the reports closed by the V1 migration triage.