{"record":{"id":"b746b33f4b62d4b4","repo":"bytedance/deer-flow","slug":"failed-to-update-mcp-configuration","errorCode":null,"errorMessage":"Failed to update MCP configuration","messagePattern":"Failed to update MCP configuration","errorType":"exception","errorClass":"MCPConfigRequestError","httpStatus":null,"severity":"error","filePath":"frontend/src/core/mcp/api.ts","lineNumber":48,"sourceCode":"  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,\n      await readErrorDetail(response, \"Failed to update MCP configuration\"),\n    );\n  }\n  return response.json();\n}\n\nexport async function updateMCPServerState(\n  serverName: string,\n  enabled: boolean,\n) {\n  const response = await fetch(`${getBackendBaseURL()}/api/mcp/config`, {\n    method: \"PATCH\",\n    headers: {\n      \"Content-Type\": \"application/json\",\n    },\n    body: JSON.stringify({\n      server_name: serverName,","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/frontend/src/core/mcp/api.ts#L30-L66","documentation":"Thrown when PUT /api/mcp/config (full replacement of the MCP server configuration) returns non-2xx. The Gateway re-validates and atomically writes extensions_config.json; a 422 means the submitted MCPConfig failed schema validation (bad command/args/env types), while 500 usually means the file could not be written.","triggerScenarios":"Saving the MCP editor with a server entry missing required fields (e.g. command empty for a stdio server), env not an object, or url malformed for an SSE/streamable server; concurrent edits where two tabs PUT different configs; filesystem permission loss on the repo root.","commonSituations":"Editing the JSON textarea directly and leaving a trailing comma or quoting a number; switching a server between stdio and SSE types without clearing stale fields; running the Gateway in Docker where extensions_config.json is mounted read-only.","solutions":["Read the 422 'detail' — FastAPI lists the exact failing JSON path and expected type","Fix the offending server entry in the editor and re-PUT","Ensure the process running the Gateway can write extensions_config.json (check mount flags in docker-compose)","Reload GET /api/mcp/config to see the server's current canonical shape and diff your payload against it"],"exampleFix":"// before\nawait updateMCPConfig(editedConfig);\n\n// after\ntry {\n  await updateMCPConfig(editedConfig);\n} catch (e) {\n  if (e instanceof MCPConfigRequestError && e.status === 422) {\n    setFormErrors(e.message); // FastAPI detail names the invalid field\n    return;\n  }\n  throw e;\n}","handlingStrategy":"validation","validationCode":"function validateMCPConfig(config: MCPConfig): string[] {\n  const errs: string[] = [];\n  for (const [name, srv] of Object.entries(config.mcpServers ?? {})) {\n    if ('command' in srv && !srv.command) errs.push(`${name}: command required for stdio`);\n    if ('url' in srv && !/^https?:\\/\\//.test(srv.url)) errs.push(`${name}: url must be http(s)`);\n    if (srv.env !== undefined && typeof srv.env !== 'object') errs.push(`${name}: env must be an object`);\n  }\n  return errs;\n}","typeGuard":"export function isMCPConfigRequestError(e: unknown): e is MCPConfigRequestError {\n  return e instanceof MCPConfigRequestError;\n}","tryCatchPattern":"try {\n  await updateMCPConfig(config);\n} catch (e) {\n  if (isMCPConfigRequestError(e) && e.status === 422) {\n    setEditorErrors(e.message);\n    return;\n  }\n  throw e;\n}","preventionTips":["Run schema validation in the editor before enabling Save","Parse-and-stringify edited JSON in a try-catch to catch syntax errors client-side","Ensure the config file is writable by the Gateway process"],"tags":["mcp","config","validation","http","frontend"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}