bytedance/deer-flow · error

Failed to create side conversation.

Error message

Failed to create side conversation.

What it means

Thrown when POST /api/threads (creating a side conversation / sidecar thread) returns non-2xx. The request goes through fetchWithAuth, so common failures are 401/403 auth expiry and 422 when buildSidecarThreadMetadata produces a payload the backend rejects. The error message discards status and body entirely.

Source

Thrown at frontend/src/core/sidecar/api.ts:67

async function createSidecarThreadRequest({
  parentThreadId,
  context,
}: {
  parentThreadId: string;
  context: SidecarContext | SidecarContext[];
}): Promise<AgentThread> {
  const response = await fetchWithAuth(`${getBackendBaseURL()}/api/threads`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      metadata: buildSidecarThreadMetadata(parentThreadId, context),
    }),
  });

  if (!response.ok) {
    throw new Error("Failed to create side conversation.");
  }

  return (await response.json()) as AgentThread;
}

export async function findLatestSidecarThread({
  parentThreadId,
  isMock,
  apiClient = getAPIClient(isMock) as SidecarThreadSearchClient,
}: {
  parentThreadId: string;
  isMock?: boolean;
  apiClient?: SidecarThreadSearchClient;
}): Promise<AgentThread | null> {
  const response = await apiClient.threads.search({
    metadata: {
      [SIDECAR_METADATA_KEY]: true,
      parent_thread_id: parentThreadId,

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Inspect response.status in devtools (the thrown Error hides it) — 401 → re-auth, 422 → shrink/fix metadata
  2. Truncate or move large context out of thread metadata into the first message payload
  3. Confirm POST /api/threads works with a minimal body via curl before blaming metadata
  4. Retry once after Gateway /health is green if a 502 was observed

Example fix

// before
if (!response.ok) {
  throw new Error('Failed to create side conversation.');
}

// after
if (!response.ok) {
  const detail = await response.text().catch(() => '');
  throw new Error(`Failed to create side conversation (${response.status}): ${detail.slice(0, 200)}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

function sidecarMetadataSizeOk(metadata: ThreadMetadata): boolean {
  return new Blob([JSON.stringify(metadata)]).size < 32 * 1024;
}

Try / catch

try {
  return await createSidecarThread({parentThreadId, context});
} catch (e) {
  if (e instanceof Error && e.message === 'Failed to create side conversation.') {
    if (await sessionExpired()) {
      await reauthenticate();
      return createSidecarThread({parentThreadId, context});
    }
  }
  throw e;
}

Prevention

When it happens

Trigger: Opening a sidecar chat after the auth token expired (401); metadata payload with fields exceeding backend limits (413/422); Gateway restarting mid-request (502); creating threads when the persistence store is unavailable (500).

Common situations: Using side conversations during a long session; embedding very large context strings into sidecar metadata; backend upgrade that changed required thread metadata schema.

Related errors


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