bytedance/deer-flow · error

Failed to compact context.

Error message

Failed to compact context.

What it means

Thrown when POST .../compact (context compaction) returns non-2xx. The client always sends force:true plus optional agent/model overrides and forwards options.signal so user cancellation aborts the fetch. Backend failures include 404 (unknown thread), 409 (compaction not possible mid-run), 422 (invalid agent_name/model_name), and 504 when compaction of a very long thread exceeds a gateway timeout.

Source

Thrown at frontend/src/core/threads/api.ts:158

): Promise<ThreadCompactResponse> {
  const response = await fetchWithAuth(
    `${getBackendBaseURL()}/api/threads/${encodeURIComponent(threadId)}/compact`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        force: true,
        ...(options.agentName ? { agent_name: options.agentName } : {}),
        ...(options.modelName ? { model_name: options.modelName } : {}),
      }),
      signal: options.signal,
    },
  );

  if (!response.ok) {
    throw new Error(
      await readThreadAPIError(response, "Failed to compact context."),
    );
  }

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

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Check the wrapped detail: 422 names the invalid agent/model field — pick a valid one from the model list
  2. Retry after the current run finishes if the conflict is a live run
  3. On 5xx, verify the configured summarization model works (test a normal chat turn) before retrying compaction
  4. Use options.signal only for user cancel, and distinguish AbortError from this HTTP error

Example fix

// before
await compactThreadContext(threadId, {agentName});

// after
try {
  await compactThreadContext(threadId, {agentName});
} catch (e) {
  if (e instanceof Error && /invalid|unknown/i.test(e.message)) {
    return compactThreadContext(threadId, {}); // drop bad override
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

async function compactionOptionsValid(options: CompactThreadContextOptions): Promise<boolean> {
  if (!options.agentName && !options.modelName) return true;
  const models = await loadModelList();
  return (!options.agentName || models.agents.includes(options.agentName)) &&
         (!options.modelName || models.names.includes(options.modelName));
}

Type guard

export function isCompactError(e: unknown): e is Error {
  return e instanceof Error && e.message.includes('Failed to compact context.');
}

Try / catch

try {
  return await compactThreadContext(threadId, options);
} catch (e) {
  if (isCompactError(e) && /invalid|unknown/i.test(e.message)) {
    return compactThreadContext(threadId, {}); // drop bad overrides
  }
  if (isCompactError(e) && /conflict|409/i.test(e.message)) {
    return retryAfterRunCompletes(threadId, options);
  }
  throw e;
}

Prevention

When it happens

Trigger: Compacting while a run is active on the thread; passing an agent_name or model_name that doesn't exist in config.yaml (422); compacting a thread whose history was already compacted and pruned; LLM backend failure during summarization (500).

Common situations: User clicks 'compact context' on a hot thread; model was renamed in config but the UI still offers the old name; provider API outage during the summarization call.

Related errors


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