Skip to content

Web UI: client-generated message IDs cause infinite processing loop when client/server clocks diverge #11863

@KONFeature

Description

@KONFeature

Description

When sending a message from the Web UI, the user message gets an ID that sorts after all assistant message IDs, causing the processing loop in prompt.ts to never exit.

This burns tokens indefinitely in the background, and it also prevent Web UI (or desktop UI I assume), to display the right message. On the TUI side, the user message is marked as queued.

Root cause:
The Web UI generates messageID client-side (packages/app/src/utils/id.ts) before sending to the backend, while assistant message IDs are generated server-side (packages/opencode/src/id/id.ts).

Both use the same algorithm, but any clock skew between client and server means the user message ID sorts after (or before) assistant IDs, breaking the assumption that ID order = chronological order.

The loop exit condition at session/prompt.ts L296-303 checks lastUser.id < lastAssistant.id — if the user ID is "larger" (client clock ahead), the loop never breaks and keeps generating responses indefinitely.

Observed data (from the session messages endpoint, see attached JSON):

# Role ID time.created
1 assistant msg_c1f6b1d57001RHuvN3zOJhP9vQ 1770053639511
2 assistant msg_c1f6b7956001ie0EeKm2LsYp68 1770053663062
3 assistant msg_c1f71ddc4001pBbmRnquIAmNbi 1770054081988
4 user msg_c20455b9d001RX64FkeGhqcCIC 1770053639500

The user message was created 11ms before the first assistant message (time.created: 1770053639500 vs 1770053639511), yet its ID timestamp hex (c20455b9d001) sorts after all assistant ID prefixes (c1f6..., c1f7...). The assistant messages reference the user message as parentID, confirming it's the original prompt.

session-output.json

This causes the loop to see lastUser.id > lastAssistant.id → condition to exit is never met → infinite response generation.

Potentially related to #7426 (message ordering issues with ID-based sorting).

Plugins

none

OpenCode version

1.1.48

Steps to reproduce

  1. Start OpenCode with Web UI on a remote server (where client and server clocks may differ)
  2. Send a message from the Web UI
  3. Observe: assistant responds, then immediately starts processing again
  4. Tokens burn continuously until manually stopped via TUI

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingwebRelates to opencode on web / desktop

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions