bytedance/deer-flow · error
Failed to update conversation.
Error message
Failed to update conversation.
What it means
Thrown when PATCH /api/threads/{id} with {metadata} returns non-2xx. This is the rename/tag/update-conversation call; readThreadAPIError surfaces the backend reason. 404 means the thread no longer exists, 409 usually a conflicting concurrent patch (metadata merge failure), 422 metadata that fails the backend's schema/size limits.
Source
Thrown at frontend/src/core/threads/api.ts:129
}
export async function patchThreadMetadata(
threadId: string,
metadata: ThreadMetadataPatch,
): Promise<ThreadMetadataPatchResponse> {
const response = await fetchWithAuth(
`${getBackendBaseURL()}/api/threads/${encodeURIComponent(threadId)}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ metadata }),
},
);
if (!response.ok) {
throw new Error(
await readThreadAPIError(response, "Failed to update conversation."),
);
}
return (await response.json()) as ThreadMetadataPatchResponse;
}
export async function compactThreadContext(
threadId: string,
options: CompactThreadContextOptions = {},
): Promise<ThreadCompactResponse> {
const response = await fetchWithAuth(
`${getBackendBaseURL()}/api/threads/${encodeURIComponent(threadId)}/compact`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},View on GitHub (pinned to 1dd6ba1acb)
Solutions
- On 404, drop the local thread from the list — it was deleted server-side
- On 409, re-fetch the thread, re-apply the user's edit onto fresh metadata, patch again
- Keep metadata values within backend limits (truncate long titles client-side)
- Debounce rapid successive edits into one PATCH
Example fix
// before
await patchThreadMetadata(threadId, {title});
// after
try {
await patchThreadMetadata(threadId, {title});
} catch (e) {
if (/409|conflict/i.test(e.message)) {
await reloadThread(threadId);
await patchThreadMetadata(threadId, {title}); // one re-apply
return;
}
throw e;
} Defensive patterns
Strategy: retry
Validate before calling
function metadataPatchOk(metadata: ThreadMetadataPatch): boolean {
const s = JSON.stringify(metadata);
return s.length <= 4096 && Object.values(metadata).every((v) => v !== undefined);
} Type guard
export function isThreadPatchError(e: unknown): e is Error {
return e instanceof Error && e.message.includes('Failed to update conversation.');
} Try / catch
try {
return await patchThreadMetadata(threadId, metadata);
} catch (e) {
if (isThreadPatchError(e) && /conflict|409/i.test(e.message)) {
await reloadThread(threadId);
return patchThreadMetadata(threadId, metadata); // one optimistic retry
}
throw e;
} Prevention
- Truncate long titles client-side before PATCH
- Debounce rapid metadata edits into one request
- On 404, remove the thread from local state
When it happens
Trigger: Renaming a thread deleted in another tab (404); two rapid metadata patches racing (409); metadata values exceeding size limits or containing disallowed keys (422); session expired (401).
Common situations: Editing title/tags while an agent run also updates thread metadata; very long pasted titles; multi-tab usage.
Related errors
- Failed to create side conversation.
- Failed to load thread token usage.
- Failed to branch conversation.
- Failed to compact context.
- Failed to load MCP configuration
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/4a7bf32a6a8cad25.
Report an issue: GitHub.