{"record":{"id":"636e679172b04ce6","repo":"bytedance/deer-flow","slug":"failed-to-load-mcp-configuration","errorCode":null,"errorMessage":"Failed to load MCP configuration","messagePattern":"Failed to load MCP configuration","errorType":"exception","errorClass":"MCPConfigRequestError","httpStatus":null,"severity":"error","filePath":"frontend/src/core/mcp/api.ts","lineNumber":31,"sourceCode":"  get isAdminRequired(): boolean {\n    return this.status === 403;\n  }\n}\n\nasync function readErrorDetail(\n  response: Response,\n  fallback: string,\n): Promise<string> {\n  const error = (await response.json().catch(() => ({}))) as {\n    detail?: unknown;\n  };\n  return typeof error.detail === \"string\" ? error.detail : fallback;\n}\n\nexport async function loadMCPConfig() {\n  const response = await fetch(`${getBackendBaseURL()}/api/mcp/config`);\n  if (!response.ok) {\n    throw new MCPConfigRequestError(\n      response.status,\n      await readErrorDetail(response, \"Failed to load MCP configuration\"),\n    );\n  }\n  return response.json() as Promise<MCPConfig>;\n}\n\nexport async function updateMCPConfig(config: MCPConfig) {\n  const response = await fetch(`${getBackendBaseURL()}/api/mcp/config`, {\n    method: \"PUT\",\n    headers: {\n      \"Content-Type\": \"application/json\",\n    },\n    body: JSON.stringify(config),\n  });\n  if (!response.ok) {\n    throw new MCPConfigRequestError(\n      response.status,","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/frontend/src/core/mcp/api.ts#L13-L49","documentation":"Thrown when GET /api/mcp/config fails. This endpoint reads the Gateway-side MCP server registry (extensions_config.json plus runtime state); any non-2xx aborts loading of the MCP configuration UI. The error class MCPConfigRequestError carries the HTTP status and the backend 'detail' text.","triggerScenarios":"Gateway not fully started when the settings page fetches config; extensions_config.json corrupted or unreadable (500); an MCP server entry whose schema the backend rejects at load; nginx proxy returning 502 while the Gateway restarts.","commonSituations":"Opening the MCP settings panel right after `make dev` before the Gateway is listening; hand-editing extensions_config.json and introducing JSON syntax errors; upgrading the backend to a version with a stricter MCP config schema while stale entries remain.","solutions":["curl http://127.0.0.1:8001/api/mcp/config directly to see the real status and 'detail' body","Validate extensions_config.json with a JSON linter and fix syntax errors","Remove or migrate MCP server entries that use fields removed in the current backend version (compare against extensions_config.example.json)","If a 502/503 came from nginx, wait for or restart the Gateway and retry"],"exampleFix":"// before\nconst config = await loadMCPConfig();\n\n// after\nconst config = await loadMCPConfig().catch((e) => {\n  if (e instanceof MCPConfigRequestError && e.status >= 500) {\n    toast.error('MCP config unavailable on the server; retry after Gateway restart');\n  }\n  throw e;\n});","handlingStrategy":"retry","validationCode":"async function gatewayHealthy(baseURL: string): Promise<boolean> {\n  try {\n    const r = await fetch(`${baseURL}/health`);\n    return r.ok;\n  } catch {\n    return false;\n  }\n}","typeGuard":"export function isMCPConfigRequestError(e: unknown): e is MCPConfigRequestError {\n  return e instanceof MCPConfigRequestError;\n}","tryCatchPattern":"try {\n  return await loadMCPConfig();\n} catch (e) {\n  if (isMCPConfigRequestError(e) && e.status >= 502) {\n    return retryWithBackoff(loadMCPConfig, {tries: 2});\n  }\n  throw e;\n}","preventionTips":["Gate settings-page fetches on /health being green","Lint extensions_config.json in CI","Diff hand-edits against extensions_config.example.json before saving"],"tags":["mcp","config","http","frontend"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}