{"record":{"id":"46e9a08074a0c824","repo":"bytedance/deer-flow","slug":"failed-to-create-side-conversation","errorCode":null,"errorMessage":"Failed to create side conversation.","messagePattern":"Failed to create side conversation\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/core/sidecar/api.ts","lineNumber":67,"sourceCode":"async function createSidecarThreadRequest({\n  parentThreadId,\n  context,\n}: {\n  parentThreadId: string;\n  context: SidecarContext | SidecarContext[];\n}): Promise<AgentThread> {\n  const response = await fetchWithAuth(`${getBackendBaseURL()}/api/threads`, {\n    method: \"POST\",\n    headers: {\n      \"Content-Type\": \"application/json\",\n    },\n    body: JSON.stringify({\n      metadata: buildSidecarThreadMetadata(parentThreadId, context),\n    }),\n  });\n\n  if (!response.ok) {\n    throw new Error(\"Failed to create side conversation.\");\n  }\n\n  return (await response.json()) as AgentThread;\n}\n\nexport async function findLatestSidecarThread({\n  parentThreadId,\n  isMock,\n  apiClient = getAPIClient(isMock) as SidecarThreadSearchClient,\n}: {\n  parentThreadId: string;\n  isMock?: boolean;\n  apiClient?: SidecarThreadSearchClient;\n}): Promise<AgentThread | null> {\n  const response = await apiClient.threads.search({\n    metadata: {\n      [SIDECAR_METADATA_KEY]: true,\n      parent_thread_id: parentThreadId,","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/frontend/src/core/sidecar/api.ts#L49-L85","documentation":"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.","triggerScenarios":"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).","commonSituations":"Using side conversations during a long session; embedding very large context strings into sidecar metadata; backend upgrade that changed required thread metadata schema.","solutions":["Inspect response.status in devtools (the thrown Error hides it) — 401 → re-auth, 422 → shrink/fix metadata","Truncate or move large context out of thread metadata into the first message payload","Confirm POST /api/threads works with a minimal body via curl before blaming metadata","Retry once after Gateway /health is green if a 502 was observed"],"exampleFix":"// before\nif (!response.ok) {\n  throw new Error('Failed to create side conversation.');\n}\n\n// after\nif (!response.ok) {\n  const detail = await response.text().catch(() => '');\n  throw new Error(`Failed to create side conversation (${response.status}): ${detail.slice(0, 200)}`);\n}","handlingStrategy":"try-catch","validationCode":"function sidecarMetadataSizeOk(metadata: ThreadMetadata): boolean {\n  return new Blob([JSON.stringify(metadata)]).size < 32 * 1024;\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await createSidecarThread({parentThreadId, context});\n} catch (e) {\n  if (e instanceof Error && e.message === 'Failed to create side conversation.') {\n    if (await sessionExpired()) {\n      await reauthenticate();\n      return createSidecarThread({parentThreadId, context});\n    }\n  }\n  throw e;\n}","preventionTips":["Keep sidecar context out of thread metadata — send as first message","Re-auth before creating threads in long sessions","Improve the thrown message to include status for debuggability"],"tags":["sidecar","threads","http","frontend"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}