bytedance/deer-flow · warning · HTTPException

Only the latest assistant message can be regenerated

Error message

Only the latest assistant message can be regenerated

What it means

Raised in _prepare_regenerate_payload (HTTP 409) when the target assistant message is visible but is not the most recent visible AI message in the checkpoint. Regeneration rewinds the thread to replay, so only the latest assistant response qualifies; older ones would silently discard later conversation.

Source

Thrown at backend/app/gateway/routers/thread_runs.py:662

    if target_index is None:
        # A response interrupted during an LLM call can be visible in the live
        # stream without ever reaching a checkpoint. The server-stamped run ID
        # on the latest user message is the durable link to that partial turn.
        previous_human = next(
            (message for message in reversed(messages) if _is_visible_human_message(message)),
            None,
        )
        target_run_id = await _find_interrupted_target_run_id(thread_id, previous_human, request) if previous_human is not None else None
        if target_run_id is None:
            raise HTTPException(status_code=404, detail=f"Message {message_id} not found")
    else:
        target_message = messages[target_index]
        if not _is_visible_ai_message(target_message):
            raise HTTPException(status_code=409, detail="Only visible assistant messages can be regenerated")

        latest_visible_ai = next((message for message in reversed(messages) if _is_visible_ai_message(message)), None)
        if _message_id(latest_visible_ai) != message_id:
            raise HTTPException(status_code=409, detail="Only the latest assistant message can be regenerated")

        previous_human = next((message for message in reversed(messages[:target_index]) if _is_visible_human_message(message)), None)
        target_run_id = (
            await _find_target_run_id(
                thread_id,
                message_id,
                target_message,
                previous_human,
                request,
            )
            if previous_human is not None
            else None
        )
    if previous_human is None:
        raise HTTPException(status_code=409, detail="Could not find the user message for this assistant response")
    if target_run_id is None:
        raise HTTPException(status_code=409, detail="Could not find source run for assistant message")
    previous_human_id = _message_id(previous_human)

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Refresh thread state and regenerate the last visible assistant message only.
  2. Disable regenerate buttons on all but the newest assistant turn in the UI.
  3. If an older answer must change, edit the latest turn or start a new thread with clarifying context.

Example fix

// before
regeneratePrepare(threadId, anyAiMessageId);
// after
const lastAi = [...messages].reverse().find(m => m.type === 'ai' && !m.hidden);
if (lastAi?.id === chosenId) regeneratePrepare(threadId, chosenId);
Defensive patterns

Strategy: validation

Validate before calling

const lastAi = [...messages].reverse().find(m => m.type === 'ai' && !m.hidden);
if (lastAi?.id !== messageId) { targetLatestInstead(); }

Type guard

function isLatestVisibleAi(messages: Msg[], id: string): boolean {
  for (let i = messages.length - 1; i >= 0; i--) {
    if (messages[i].type === 'ai' && !messages[i].hidden) return messages[i].id === id;
  }
  return false;
}

Try / catch

try { await regeneratePrepare(threadId, messageId); } catch (e) { if (e.status === 409 && /latest assistant message/.test(e.detail)) { await refreshThread(threadId); } else throw e; }

Prevention

When it happens

Trigger: Regenerating an assistant message from an earlier turn while newer assistant responses exist in checkpoint state; UI keeps an older message selected after the thread advanced.

Common situations: Stale transcript view; concurrent client advanced the thread; user scrolls up and regenerates an old answer.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/5207cb1cb010a27d. Report an issue: GitHub.