{"record":{"id":"36bf70999220a76d","repo":"coleam00/Archon","slug":"error-mcp-tool-failed","errorCode":null,"errorMessage":"❌ Error: MCP tool failed","messagePattern":"❌ Error: MCP tool failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/providers/src/codex/provider.ts","lineNumber":744,"sourceCode":"            getLog().debug({ itemId: item.id, status: item.status }, 'file_change_no_changes');\n          }\n          break;\n        }\n\n        case 'mcp_tool_call': {\n          const server = item.server as string | undefined;\n          const tool = item.tool as string | undefined;\n          const mcpToolName = getMcpToolName(item);\n\n          if ((item.status as string) === 'failed') {\n            getLog().warn(\n              { server, tool, error: item.error, itemId: item.id },\n              'mcp_tool_call_failed'\n            );\n            const mcpError = item.error as { message?: string } | undefined;\n            const errMsg = mcpError?.message\n              ? `❌ Error: ${mcpError.message}`\n              : '❌ Error: MCP tool failed';\n            yield {\n              type: 'tool_result',\n              toolName: mcpToolName,\n              toolOutput: errMsg,\n              toolCallId: itemId,\n              toolOutcome: 'error',\n            };\n          } else {\n            let toolOutput = '';\n            const mcpResult = item.result as { content?: unknown } | undefined;\n            if (mcpResult?.content) {\n              if (Array.isArray(mcpResult.content)) {\n                toolOutput = JSON.stringify(mcpResult.content);\n              } else {\n                getLog().warn(\n                  {\n                    itemId: item.id,\n                    server,","sourceCodeStart":726,"sourceCodeEnd":762,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/providers/src/codex/provider.ts#L726-L762","documentation":"Fallback branch of the same MCP failure path as error 553: when item.error exists but has no usable `message` field, the yielded tool_result output is the static string '❌ Error: MCP tool failed'. This guarantees the agent receives an explicit error result (toolOutcome 'error') instead of a silent success when the MCP server's error payload is malformed or empty.","triggerScenarios":"An MCP tool call fails but the server's error item has no error object, or the error object lacks a string `message` (e.g. `{code: ...}` only, a non-Error thrown value, or a truncated/binary payload).","commonSituations":"Custom or third-party MCP servers returning non-standard error shapes; server crashes producing truncated error frames; older MCP SDK versions emitting minimal error objects; a tool that rejects the call without explaining why.","solutions":["Check the 'mcp_tool_call_failed' log entry — the raw item.error is logged there even when no message string existed.","Update or fix the MCP server to emit a structured error with a `message` field.","Reproduce the call against the server directly to find why the error payload is empty.","If the server uses an old MCP SDK, upgrade it so errors serialize with messages."],"exampleFix":"// before (server-side, non-standard error)\nthrow { code: 123 };\n// after\nthrow new Error('failed to read config file: permission denied');","handlingStrategy":"type-guard","validationCode":"// server side: ensure errors always serialize with a message\ntry {\n  await runTool(args);\n} catch (err) {\n  throw new Error(err instanceof Error ? err.message : String(err));\n}","typeGuard":"function hasMcpErrorMessage(err: unknown): err is { message: string } {\n  return typeof err === 'object' && err !== null\n    && typeof (err as { message?: unknown }).message === 'string'\n    && (err as { message: string }).message.length > 0;\n}","tryCatchPattern":"const mcpError = item.error as { message?: string } | undefined;\nconst errMsg = mcpError && hasMcpErrorMessage(mcpError)\n  ? `Error: ${mcpError.message}`\n  : 'Error: MCP tool failed'; // fallback keeps the agent informed, log carries raw error","preventionTips":["Always throw Error instances (not plain objects) in MCP tool implementations.","Upgrade MCP servers built on old SDKs so errors serialize with messages.","Include the raw item.error in server logs whenever the fallback string is used.","Test each tool's failure path, not just its success path."],"tags":["mcp","codex","tooling"],"backgroundTag":"mcp-tool-call-failed","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}