Skip to content

UI Bug: Editing assistant message duplicates reasoning block and corrupts stored content #23622

@ihatemakinganaccount

Description

@ihatemakinganaccount

When editing a model's response in Web UI that contains a reasoning block, the reasoning gets duplicated and a new copy is encased in <think></think> tags. This is recent new behaviour (I updated yesterday after about a week) and it seems unintended. Before, reasoning was non-editable at all, so it seems part of the idea was to expose it to editing.

I asked the DeepWiki bot to summarise and identify the cause. It found the (probable) affected files, but couldn't trace which commit introduced the change, since the files were apparently reorganised recently.

The following summary was written by the DeepWiki bot. It also suggested to tag @allozaur

(Sorry if this report is not up to par. I can only use GitHub with a phone app atm.)


Description

When editing an assistant message that contains a reasoning/thinking block, the reasoning content is duplicated in the display and the stored message is corrupted.

Steps to reproduce (Web UI)

  1. Use a reasoning model (e.g. Gemma 4 E4b)
  2. Ask a question and receive a response that includes a thinking block
  3. Click Edit on the assistant message
  4. Save the edit (with or without changes)

Expected behavior
The reasoning block is editable and saved correctly, with no duplication.

Actual behavior

  • In edit mode, the reasoning appears twice: once as the collapsible "Reasoning" block (rendered from reasoningContent), and again as <think>...</think> literal text in the textarea.
  • After saving, content contains <think>...</think> as embedded literal text, while reasoningContent retains the original unchanged value. This causes the duplication to persist in the rendered view.
  • When the next message is generated, the corrupted message is sent to the backend as context, with both reasoning_content and <think> tags in content.

Root cause

rawEditContent in ChatMessage.svelte (lines 48–90) reconstructs the full message for the edit textarea, wrapping reasoning in <think>...</think> tags. However, editAssistantMessage in chat.svelte.ts only writes the edited text to content and never updates or clears reasoningContent. The shouldBranch path has the same issue — it creates a new message with content: newContent but no reasoningContent field at all.

Relevant files:

  • tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessage.svelterawEditContent construction (lines 48–90)
  • tools/ui/src/lib/stores/chat.svelte.tseditAssistantMessage save paths (lines 1445–1463)

Additional notes

The REASONING_TAGS are hardcoded as <think>/</think> regardless of model. The codebase already deprecated embedding reasoning tags in content in favor of a dedicated reasoningContent field (LEGACY_REASONING_TAGS). The current approach re-introduces the same anti-pattern.

A correct fix would require editAssistantMessage to parse <think>...</think> out of the edited content, store the extracted text in reasoningContent, and store only the remaining text in content. Alternatively, reasoning could be exposed as a separate editable field in the UI rather than serialized into the textarea.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No fields configured for Bug.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions