TUI renders a user message twice when a prompt reuses an existing messageID
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 75/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- nodejs, typescript
Research direction
The issue is in packages/tui/src/context/sync.tsx where messageKey is defined. Look at how messages are keyed (currently time.created + id) and stored. The fix is to change the key to use id alone. Test by running the provided repro script with opencode serve and opencode attach, then verify the message appears only once after the change.
Written by the indexing model from the issue text.
Description
Version
opencode 1.18.32 (opencode serve + opencode attach)
Summary
Sending a prompt with the messageID of an existing message rewrites that message with a new time.created, but keeps the same id. The TUI sync store keys messages by time.created + id (packages/tui/src/context/sync.tsx, messageKey). When the second message.updated arrives, the lookup misses, so the TUI inserts a second row for the same id. Parts are keyed by message id, so both rows render the same content.
Storage is correct: the session has one message with one part. Reloading the session shows it once.
Repro
B=http://localhost:4096; H='x-opencode-directory: /tmp/dir'
SID=$(curl -s -X POST $B/session -H 'content-type: application/json' -H "$H" -d '{}' | jq -r .id)
# reserve an empty message
MID=$(curl -s -X POST $B/session/$SID/message -H 'content-type: application/json' -H "$H" \
-d '{"parts":[],"noReply":true}' | jq -r .info.id)
# reuse it
curl -s -X POST $B/session/$SID/message -H 'content-type: application/json' -H "$H" \
-d "{\"messageID\":\"$MID\",\"parts\":[{\"type\":\"text\",\"text\":\"hello\"}],\"noReply\":true}"
With opencode attach $B -s $SID open, "hello" appears in two user rows. The event stream shows two message.updated events for $MID with different time.created values.
Suggested fix
Key TUI messages by id alone. Ascending message ids already sort by creation time, so time.created in the key only breaks the lookup when a message is rewritten. Alternatively, keep the original time.created when a prompt reuses an existing messageID.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- Avg merge
- 9h 42m
- Merged PRs (30d)
- 389
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.
More from anomalyco/opencode
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
All issues in anomalyco/opencode
Similar issues
-
bug(cli): hapi doctor inline-media prints a fabricated B:\ helper-script path in packaged installs Open
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
-
Crush Open
Difficulty 1/5 Under an hour Newbie friendliness 85/100
catppuccin/catppuccin#3125 ·
-
Add a SECURITY.md Open
Difficulty 1/5 Under an hour Newbie friendliness 90/100
ElementsProject/cln-application#167 · 1 comment · 1 reaction ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Quantco/pnpm-licenses#17 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100