bytedance/deer-flow · error · MCPConfigRequestError

Failed to update MCP server

Error message

Failed to update MCP server

What it means

Thrown when PATCH /api/mcp/config with {server_name, enabled} fails. This is the toggle used to enable/disable one MCP server. The backend resolves server_name against the loaded config; unknown names yield 404, and validation/IO problems yield 4xx/5xx.

Source

Thrown at frontend/src/core/mcp/api.ts:71

  return response.json();
}

export async function updateMCPServerState(
  serverName: string,
  enabled: boolean,
) {
  const response = await fetch(`${getBackendBaseURL()}/api/mcp/config`, {
    method: "PATCH",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      server_name: serverName,
      enabled,
    }),
  });
  if (!response.ok) {
    throw new MCPConfigRequestError(
      response.status,
      await readErrorDetail(response, "Failed to update MCP server"),
    );
  }
  return response.json() as Promise<MCPConfig>;
}

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. On 404, reload the config (loadMCPConfig) and refresh the server list before retrying
  2. Ensure server_name is passed exactly as it appears as a key of the config's mcp servers map
  3. Check Gateway logs for file-write errors if status is 5xx
  4. Retry the toggle once after refreshing to rule out a transient reload window

Example fix

// before
await updateMCPServerState(name, enabled);

// after
try {
  await updateMCPServerState(name, enabled);
} catch (e) {
  if (e instanceof MCPConfigRequestError && e.status === 404) {
    await refreshServers(); // server was removed elsewhere
    return;
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

function serverExists(config: MCPConfig, name: string): boolean {
  return Object.prototype.hasOwnProperty.call(config.mcpServers ?? {}, name);
}

Type guard

export function isMCPConfigRequestError(e: unknown): e is MCPConfigRequestError {
  return e instanceof MCPConfigRequestError;
}

Try / catch

try {
  await updateMCPServerState(name, enabled);
} catch (e) {
  if (isMCPConfigRequestError(e) && e.status === 404) {
    await reloadConfigAndRefreshList();
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Toggling a server that was renamed or deleted in another session (404); toggling while the config file is being rewritten (rare 409/500); PATCHing a name with leading/trailing whitespace copied from the UI.

Common situations: Two browser tabs open on MCP settings where one removed a server and the other still shows its toggle; config edited by hand or via API between page load and click; stale UI after a Gateway restart with a different config.

Related errors


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