Skip to main content

Conversation branching or forking is supported

ab-000337 · ai-ux-patterns.feedback-control.conversation-branching
Severity: highactive

Why it matters

When a conversation takes a wrong turn twenty messages deep — a bad file upload, a misread instruction, a hallucination that the model now treats as ground truth — users need a way to rewind and try a different path without losing the useful context that came before. A strictly linear conversation forces "delete the last ten messages or start a new chat" as the only exits, both of which throw away work. Branching preserves that work.

Severity rationale

High because linear-only conversations force users to discard useful context whenever a thread derails.

Remediation

Start with edit-and-regenerate as the minimum viable branch. When a user edits a prior message, truncate state to that point and call reload() to regenerate from the edited turn. Full tree branching requires a parent_message_id column on the messages table and a tree-rendering sidebar; ship the minimum first. Implement in src/components/chat/message-actions.tsx.

setMessages(messages.slice(0, editIndex).concat({ ...messages[editIndex], content: newContent }))
reload()

Detection

  • ID: ai-ux-patterns.feedback-control.conversation-branching

  • Severity: high

  • What to look for: Count all conversation state management patterns in the data model. Enumerate whether the data model supports branching: check for parentMessageId fields, version history on messages, tree-structured state, or edit-and-regenerate handlers. Look for "fork from here", "branch", or "continue from this point" actions on individual messages. At least 1 branching mechanism must exist.

  • Pass criteria: Users can either (a) branch a conversation from a specific message, creating a parallel thread, or (b) edit a prior user message to create a new continuation (which is a minimal branching implementation). At least 1 branching mechanism must be implemented. Report the count on pass: "Found X branching mechanisms."

  • Fail criteria: Conversations are entirely linear — no forking, no edit-and-regenerate. Users can only append new messages.

  • Skip (N/A) when: Same as regeneration-button.

  • Detail on fail: "Conversation is strictly linear — message state is a flat array with no parentMessageId, no forking UI, and no edit-and-regenerate capability".

  • Remediation: Full branching is complex. Start with edit-and-regenerate as a minimum viable branching pattern.

    For edit-and-regenerate (minimal branching):

    const handleEditAndRegenerate = (messageIndex: number, newContent: string) => {
      // Keep all messages up to and including the edited user message
      const truncated = [
        ...messages.slice(0, messageIndex),
        { ...messages[messageIndex], content: newContent }
      ]
      setMessages(truncated)
      // Trigger regeneration from this point
      reload()
    }
    

    For full branching, consider a parentId field on messages and a tree-rendering component. This is a larger feature — the Vercel AI SDK useChat hook supports experimental_resume for multi-turn management.


Taxons

History