{"record":{"id":"b4aa22c623fea5e9","repo":"different-ai/openwork","slug":"failed-to-run-mcp-tool-response-status","errorCode":null,"errorMessage":"Failed to run MCP tool (${response.status}).","messagePattern":"Failed to run MCP tool \\((.+?)\\)\\.","errorType":"exception","errorClass":"ExternalMcpToolRunError","httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/dashboard/_components/mcp-connections-data.tsx","lineNumber":373,"sourceCode":"      const { response, payload } = await requestJson(\n        `/v1/mcp-connections/${encodeURIComponent(connectionId)}/tools/call`,\n        {\n          method: \"POST\",\n          headers: getOrgScopeHeaders(requireOrgId(orgId)),\n          body: JSON.stringify(input),\n        },\n        RUN_TOOL_REQUEST_TIMEOUT_MS,\n      );\n      if (!response.ok) {\n        if (response.status === 403 && isRecord(payload) && payload.error === \"policy_blocked\") {\n          throw new ExternalMcpToolPolicyBlockedError(\n            typeof payload.message === \"string\" ? payload.message : \"This tool is disabled by organization policy.\",\n            typeof payload.disabledBy === \"string\" ? payload.disabledBy : null,\n            typeof payload.disabledAt === \"string\" ? payload.disabledAt : null,\n          );\n        }\n        const requestError = getRequestError(payload, response, `Failed to run MCP tool (${response.status}).`);\n        throw new ExternalMcpToolRunError(\n          requestError.message,\n          isRecord(payload) ? parseToolCallInspection(payload.inspection) : null,\n          isRecord(payload) ? parseExternalMcpDiagnostic(payload.diagnostic) : null,\n        );\n      }\n      if (\n        !isRecord(payload)\n        || typeof payload.referenceId !== \"string\"\n        || typeof payload.durationMs !== \"number\"\n        || !(\"result\" in payload)\n      ) {\n        throw new Error(\"MCP tool result was incomplete.\");\n      }\n      return {\n        referenceId: payload.referenceId,\n        durationMs: payload.durationMs,\n        result: payload.result,\n        // A missing or unparseable inspection must not fail a tool run that","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_components/mcp-connections-data.tsx#L355-L391","documentation":"When a run-tool request fails with any non-403-policy status, the hook builds the message via getRequestError(payload, response, `Failed to run MCP tool (${response.status}).`) and wraps it in ExternalMcpToolRunError together with any inspection and diagnostic payloads the server attached. The template string is only the fallback — the real message comes from the response body — so this error represents a concrete server-side tool execution failure with attribution data.","triggerScenarios":"MCP server unreachable or returned an error; auth to the external MCP failed (401/403 non-policy); tool input rejected (4xx); upstream timeout (504) within RUN_TOOL_REQUEST_TIMEOUT_MS; any non-ok status other than the 403 policy_blocked case.","commonSituations":"Expired OAuth credentials on the connection (needs reconnect); wrong tool input schema; external MCP server down or DNS/network failure from the den server; per-member credential mode where the calling member never connected.","solutions":["Read error.inspection and error.diagnostic on ExternalMcpToolRunError for the server-side failure attribution","Check the connection's credentialHealth; re-authorize if reconnect_required","Validate the tool input against the catalog's inputSchema before calling","Retry only after fixing the underlying cause (connectivity, credentials, or input)"],"exampleFix":"// before\nawait runTool({ tool: name, input });\n// after\ntry {\n  await runTool({ tool: name, input });\n} catch (err) {\n  if (err instanceof ExternalMcpToolRunError) {\n    console.error(\"Tool run failed:\", err.message, err.inspection, err.diagnostic);\n  }\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"function isValidToolInput(tool: ExternalMcpTool, input: unknown): boolean {\n  // validate against tool.inputSchema (JSON Schema) before the run call\n  return validateJsonSchema(input, tool.inputSchema);\n}","typeGuard":"function isToolRunError(e: unknown): e is ExternalMcpToolRunError {\n  return e instanceof ExternalMcpToolRunError;\n}","tryCatchPattern":"try {\n  await runTool({ tool, input });\n} catch (err) {\n  if (err instanceof ExternalMcpToolRunError) {\n    console.error(err.message, { inspection: err.inspection, diagnostic: err.diagnostic });\n    // route 401/403 to reconnect flow, 5xx to retry-after-check\n  }\n}","preventionTips":["Validate tool input against the catalog inputSchema before invoking","Monitor connection credentialHealth and prompt reconnect proactively","Use inspection/diagnostic fields for user-facing attribution instead of retrying blindly"],"tags":["mcp","network","tool-execution","api-error"],"backgroundTag":"mcp-tool-execution-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}