Repository navigation
Description
Before submitting
- I searched existing issues and did not find a duplicate. (Closest is [Bug]: visualize output is shown as raw tool text instead of rendering the visualization #7191 — same class, different path.)
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- In any thread, invoke
html_rendernested inside another tool call (outer recorded toolName differs — e.g. anexecutesandbox, or emitting a bare reference like [Bug]: visualize output is shown as raw tool text instead of rendering the visualization #7191'svisualize{"path":…}), with thread scope. - Call returns success:
{htmlRender: {attachmentId, …}, message: "Shown to the reader above your reply…"}. - Observe: no frame in web/desktop/mobile. The file exists at
userdata/attachments/<thread>-<uuid>-html.html.
Expected behavior
The page displays — or the call fails honestly.
Actual behavior
Silent orphan. Invisible in all clients, missing from attachment accounting, survives thread deletion and the stale-attachment sweeper (which skips non-pending- files).
Impact
Major degradation or frequent failure
Version or commit
0.0.46-nightly.20261011.2955
Environment
Windows x64, web client (provider-independent — see note)
Logs or stack traces
{"htmlRender": {"attachmentId": "2be2677d-…-d5eeb9f9-…-html", "title": "Yes - demo charts", "height": 408}, "message": "Shown to the reader above your reply. …"}Workaround
Call html_render directly in the provider tool loop — that path displays on all providers, including OpenCode CLI (per-thread t3-code-<thread>_* spellings resolve). Only nested/sandboxed invocation orphans.
Note (not provider-specific)
This is about the call path, not the provider brand. Direct-loop calls resolve and display (verified in code for mcp__t3-code__html_render and OpenCode per-thread spellings); a Claude/Codex agent invoking from inside a wrapper would orphan exactly the same way.
Evidence
3 orphan -html.html files on disk for one thread; statev2.sqlite: 116 turn items, 44 mention the string, 0 turn items actually named html_render.
Root cause
Handler requires only thread scope (apps/server/src/mcp/toolkits/html/handlers.ts:41-55); publish stores + returns ref, records nothing (apps/server/src/htmlRender/HtmlRender.ts:416-448, cf. comment at :437-439); all discovery scans turn items only (packages/shared/src/toolOutput.ts:186-193, apps/server/src/attachmentStore.ts:123-137; apps/web/src/session-logic.ts:717-730, apps/mobile/src/lib/threadActivity.ts:1781-1795, apps/server/src/orchestration-v2/ProjectionStore.ts:4736-4742/:6245-6260); scope carries no run/node id so nested vs top-level is indistinguishable (apps/server/src/mcp/McpInvocationContext.ts:53-61).
Fix sizing
No small correct fix — fail-fast needs new invocation attribution across adapters (M); self-recording publish needs an MCP→projection write path + dedup (M-L). Verified by 3 independent code+DB checks; details on request.
Activity
juliusmarminge commentedon Oct 11, 2026
Note
Grok responding on behalf of Julius.
Thanks for the detailed write-up. This is the same problem tracked in #16745:
html_rendercalled from inside a wrapper like OpenCode'sexecutepublishes the page, but clients only look for turn items namedhtml_render, so the page never shows and isn't cleaned up on thread delete. That issue also covers the case where the wrapper's output doesn't carry the reference at all. The fix is in progress in #17031.Closing this as a duplicate so the discussion stays in one place. If you hit this through a wrapper that #17031 wouldn't cover, please add that detail on #16745.