Skip to content

Web UI repeatedly 404s when assistant parentID points to a removed message #36371

Closed

Description

@su-351917

AI-assisted report: this issue was investigated and written with help from an AI assistant. The observations below are based on local DB/API inspection; sensitive transcript content and local project paths have been intentionally omitted.

Summary

The OpenCode web UI repeatedly shows a 404 error:

NotFoundError: Message not found: msg_...

This can appear across multiple browsers/devices, and it can continue to appear even after opening a new session.

The root cause appears to be a logical DB inconsistency: an assistant message remains in the message table with parentID pointing to a user message that has been removed via a message.removed.1 event.

Environment

opencode version: 1.17.18
OS: Linux 7.0.0-27-generic x64
terminal: vscode 1.121.0 / xterm-256color
plugins: none
mode: opencode web --hostname 127.0.0.1 --port 4096

Affected historical sessions in the local DB included sessions created with versions 1.17.13 and 1.17.18.

Observed behavior

The web UI repeatedly displayed an error like:

Error: Message not found: msg_f4f9877d90013TMgCeYSd6VD56

body: {
  "name": "NotFoundError",
  "data": {
    "message": "Message not found: msg_f4f9877d90013TMgCeYSd6VD56"
  }
}
status: 404

The same error was reproducible through the local API:

GET /session/{sessionID}/message/{missingMessageID}
=> 404 {"name":"NotFoundError","data":{"message":"Message not found: ..."}}

But GET /session/{sessionID}/message still returned 200, so the session message list endpoint itself was not completely broken.

DB integrity checks

SQLite physical integrity looked OK:

PRAGMA quick_check;      -- ok
PRAGMA integrity_check;  -- ok

So this does not look like raw SQLite file corruption.

Logical inconsistency found

There were assistant messages whose parentID did not exist in the message table.

Sanitized detection query:

WITH parents AS (
  SELECT id, session_id, json_extract(data, '$.parentID') AS parent_id
  FROM message
  WHERE json_extract(data, '$.parentID') IS NOT NULL
)
SELECT p.id AS child_message_id, p.session_id, p.parent_id AS missing_parent_id
FROM parents p
LEFT JOIN message m ON m.id = p.parent_id
WHERE m.id IS NULL;

In this local DB, it found 10 dangling parent references.

For the specific failing message ID, the event log still contained:

message.updated.1       -- for the removed user message
message.part.updated.1  -- for the text part of that user message
message.removed.1       -- removing that user message

But an assistant message still had:

{"parentID":"msg_f4f9877d90013TMgCeYSd6VD56", "role":"assistant", ...}

The removed parent message no longer existed in the message table, causing the API to return 404 when the UI attempted to resolve it.

Likely trigger

The affected rows were associated with abort/error/reconnect-like situations, including MessageAbortedError and APIError assistant messages.

This was observed across multiple model IDs in the local DB, including gpt-5.5, gpt-5.6, gpt-5.6-luna, and gpt-5.6-sol. It does not look strictly model-specific, although newer model/API behavior may make the race easier to trigger.

Workaround that fixed the local instance

Restoring the missing parent message rows and their part rows from the append-only event log made the API return 200 again for the previously missing message, and removed the repeated UI error.

After repair:

dangling parent references: 10 -> 0
orphan parts: 0
PRAGMA integrity_check: ok
GET /session/{sessionID}/message/{previouslyMissingMessageID}: 200

Expected behavior

One of the following would avoid the UI-breaking state:

  • message.removed should not leave child assistant messages with parentID pointing to a removed message.
  • The API/UI should tolerate missing parent messages and render a placeholder instead of throwing a fatal 404.
  • A migration/check/repair path could detect and fix dangling parentID references.

Actual behavior

A removed user message can still be referenced by an assistant message's parentID, and the web UI repeatedly surfaces Message not found errors when it tries to resolve that parent message.

Activity

  1. github-actions commented on Jul 11, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of or closely related to existing issues. Please check:

  2. su-351917 commented on Jul 12, 2026

    @su-351917
    Author

    Additional recurrence after local repair:

    After the previous DB repair had reduced dangling parent references to 0, the same condition occurred again with a new missing message ID.

    Sanitized facts:

    opencode version: 1.17.18
    missing user message: msg_f56365680001bYxduCcjVcuOgo
    child assistant message: msg_f56365122001TF7xnZSuFMAGHz
    child model: openai/gpt-5.6, variant xhigh
    child error: APIError
    

    Before repair:

    message.id exact count for missing ID: 0
    part.message_id exact count for missing ID: 0
    message.removed.1 events for missing ID: 1
    message.updated.1 events for missing ID: 4
    message.part.updated.1 events for missing ID: 5
    dangling parent references: 1
    SQLite quick_check: ok
    

    The child assistant message had parentID pointing to the missing/removed user message. Restoring the missing parent message row and one part row from the event log again fixed the local API result:

    dangling parent references: 1 -> 0
    orphan parts: 0
    SQLite integrity_check: ok
    GET /session/{sessionID}/message/msg_f56365680001bYxduCcjVcuOgo: 404 -> 200
    

    This confirms the issue can recur after repairing previous dangling references, and it is not just a one-time historical DB artifact.

  3. opencode-agent commented on Jul 20, 2026

    @opencode-agent
    Contributor

    Fixed by #37918.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions