Repository navigation
Text Duplication in Chat Response UI #13658
Description
Description
Bug Report: Text Duplication in Chat Response UI
Summary
Sometime, AI-generated text responses were being duplicated in the opencode client UI, displaying the same content twice (e.g., "Direttive correttamente assimilate. Procedere con l'assimilazione dei tools disponibili?Direttive correttamente assimilate. Procedere con l'assimilazione dei tools disponibili?").
Root Cause Analysis
The duplication was caused by a dual rendering mechanism in the client-side UI component that was not properly synchronized:
1. Affected Component
File: packages/ui/src/components/session-turn.tsx
2. Rendering Architecture
The SessionTurn component renders assistant messages through two separate paths:
Path A: AssistantMessageItem (Line 729-747)
- Renders all parts of assistant messages including text parts
- Controlled by the
hideResponsePartprop to filter out the last text part - Displays text during the streaming process
Path B: Summary Section (Line 756-793)
<Show when={!working() && response()}>
<div data-slot="session-turn-summary-section">
<Markdown text={response() ?? ""} cacheKey={responsePartId()} />
</div>
</Show>- Renders the final response text at the bottom when
working()is false - Intended to show a clean summary after streaming completes
3. The Bug
The hideResponsePart logic in the AssistantMessageItem component (Line 158-181) was not working correctly:
Original problematic code:
if (props.hideResponsePart) {
const responsePartId = props.responsePartId
if (responsePartId && responsePartId === lastTextPart()?.id) {
parts = parts.filter((part) => part?.id !== responsePartId)
}
}Issues identified:
- The comparison
responsePartId === lastTextPart()?.idwas unreliable due to SolidJS reactivity timing lastTextPart()is a memo that might return a different reference or stale value- The condition was too restrictive - it required both IDs to match exactly, which could fail during streaming state transitions
Impact
- All streaming text responses were duplicated in the UI
- User experience severely degraded with repeated text
- Only affected the display layer, not the underlying data or API responses
Fix Applied
Modified the filtering logic in session-turn.tsx (Line 158-181):
Fixed code:
if (props.hideResponsePart) {
const responsePartId = props.responsePartId
const lastPart = lastTextPart()
// DEBUG: Log for tracking duplication issues
console.log("[SessionTurn] hideResponsePart:", props.hideResponsePart,
"responsePartId:", responsePartId,
"lastTextPart?.id:", lastPart?.id,
"lastTextPart?.text:", lastPart?.text?.slice(0, 50))
if (responsePartId) {
// FIX: Always filter when hideResponsePart is true and we have a valid responsePartId
// Don't compare with lastTextPart, filter directly by ID
const filtered = parts.filter((part) => part?.id !== responsePartId)
console.log("[SessionTurn] Parts filtered:", parts.length, "->", filtered.length)
parts = filtered
}
}Key Changes:
- Removed unreliable comparison: No longer depends on
responsePartId === lastTextPart()?.id - Simplified logic: Filter by
responsePartIddirectly whenhideResponsePartis true - Added debugging: Console logs to track filtering behavior during development
Verification Steps
- Build the opencode client:
npm run buildorpnpm build - Start a new chat session
- Send any message to trigger AI response
- Observe that text appears only once, not duplicated
- Check browser console for
[SessionTurn]debug logs
Additional Notes
- The ChromeOpenAPIProxy server was working correctly and sending responses only once
- This was purely a client-side rendering issue
- The fix maintains backward compatibility with existing functionality
- No changes required to the proxy or API layer
Related Files
- Client UI:
packages/ui/src/components/session-turn.tsx - Stream Processing:
packages/opencode/src/session/processor.ts - Event Handling:
packages/app/src/context/global-sync/event-reducer.ts
Plugins
No response
OpenCode version
No response
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
Activity
alexyaroshuk commentedon Feb 14, 2026
? "Fix applied"? What is this? AI output?