bytedance/deer-flow · error

Failed to load thread history.

Error message

Failed to load thread history.

What it means

Default message for a non-ok response when loading thread history pages (GET /api/threads/{id}/messages?before=...) via React Query useInfiniteQuery. readResponseErrorMessage tries the body's detail first; this literal is the fallback. Subsequent parsing failures are handled separately by parseThreadMessagesPageResponse.

Source

Thrown at frontend/src/core/threads/hooks.ts:2643

    queryKey: threadHistoryQueryKey(threadId),
    enabled: enabled && Boolean(threadId),
    initialPageParam: null,
    queryFn: async ({ pageParam, signal }) => {
      const url = buildThreadMessagesPageUrl(
        getBackendBaseURL(),
        threadId,
        pageParam ?? undefined,
      );
      const response = await fetch(url, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
        },
        credentials: "include",
        signal,
      });
      if (!response.ok) {
        throw new Error(
          await readResponseErrorMessage(
            response,
            "Failed to load thread history.",
          ),
        );
      }
      return parseThreadMessagesPageResponse(await response.json());
    },
    getNextPageParam: getThreadHistoryNextPageParam,
  });

  const currentMessageRows = useMemo(
    () => flattenThreadHistoryPages(historyQuery.data?.pages ?? []),
    [historyQuery.data?.pages],
  );
  const [retainedHistory, setRetainedHistory] = useState<{
    threadId: string;
    rows: RunMessage[];

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Read the HTTP status of the failing /messages request in the Network tab — it distinguishes auth, missing-thread, and server errors.
  2. 404: navigate back to the thread list; the thread no longer exists server-side.
  3. 401/403: log in again and let React Query refetch.
  4. 5xx: check gateway logs; if it recurs on one thread, that thread's data may be corrupt — try the support-bundle/doctor tooling.
Defensive patterns

Strategy: retry

Validate before calling

// Before navigating, optionally HEAD the thread: await fetch(`/api/threads/${id}`, { method: 'HEAD' }) — 404 means don't attempt history load.

Try / catch

try { const page = await fetchThreadHistory(threadId, param, signal); } catch (e) { if (isAuthError(e)) await relogin(); else if (isNotFound(e)) router.replace('/'); else queryClient.invalidateQueries(historyKey); throw e; }

Prevention

When it happens

Trigger: History fetch returns 404 (thread pruned/never existed), 401/403 (expired session), 429 (rate limited), 500 (gateway serializer crash), or any error body without a 'detail' field so the fallback text is used.

Common situations: Opening a thread link after the thread was deleted, gateway restart during pagination, cookie expiry in a background tab refreshing queries, or a proxy timeout on very long histories.

Related errors


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