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.
Version
opencode 1.18.32 (
opencode serve+opencode attach)Summary
Sending a prompt with the
messageIDof an existing message rewrites that message with a newtime.created, but keeps the same id. The TUI sync store keys messages bytime.created + id(packages/tui/src/context/sync.tsx,messageKey). When the secondmessage.updatedarrives, 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
With
opencode attach $B -s $SIDopen, "hello" appears in two user rows. The event stream shows twomessage.updatedevents for$MIDwith differenttime.createdvalues.Suggested fix
Key TUI messages by
idalone. Ascending message ids already sort by creation time, sotime.createdin the key only breaks the lookup when a message is rewritten. Alternatively, keep the originaltime.createdwhen a prompt reuses an existingmessageID.