{"record":{"id":"eaae1ba44608f63d","repo":"yikart/AiToEarn","slug":"internalerror","errorCode":"InternalError","errorMessage":"Tool result does not match outputSchema: ${validation.error.message}","messagePattern":"Tool result does not match outputSchema: (.+?)","errorType":"error_code","errorClass":"McpError","httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/libs/nest-mcp/src/services/handlers/mcp-tools.handler.ts","lineNumber":46,"sourceCode":"\n  private buildDefaultContentBlock(result: any) {\n    return [\n      {\n        type: 'text',\n        text: JSON.stringify(result),\n      },\n    ]\n  }\n\n  private formatToolResult(result: any, outputSchema?: ZodTypeAny): any {\n    if (result && typeof result === 'object' && Array.isArray(result.content)) {\n      return result\n    }\n\n    if (outputSchema) {\n      const validation = outputSchema.safeParse(result)\n      if (!validation.success) {\n        throw new McpError(\n          ErrorCode.InternalError,\n          `Tool result does not match outputSchema: ${validation.error.message}`,\n        )\n      }\n      return {\n        structuredContent: result,\n        content: this.buildDefaultContentBlock(result),\n      }\n    }\n\n    return {\n      content: this.buildDefaultContentBlock(result),\n    }\n  }\n\n  registerHandlers(mcpServer: McpServer, httpRequest: HttpRequest) {\n    if (this.registry.getTools(this.mcpModuleId).length === 0) {\n      this.logger.debug('No tools registered, skipping tool handlers')","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/libs/nest-mcp/src/services/handlers/mcp-tools.handler.ts#L28-L64","documentation":"After a tool executes, formatToolResult validates the raw result against the tool's declared Zod outputSchema. If the tool's return value does not conform, the handler throws McpError InternalError, because returning structuredContent that violates the advertised schema would break the MCP contract.","triggerScenarios":"A tool implementation returns data that fails outputSchema.safeParse — missing required fields, wrong types, extra/null fields where the schema forbids them, or unparsed JSON strings returned instead of objects.","commonSituations":"Schema tightened after the tool code was written; tool returns null/undefined on an internal failure path; remote API change altered the response shape; developer returned the raw SDK response instead of the mapped object.","solutions":["Align the tool's return value with its declared outputSchema (map/normalize the result before returning)","Run the schema in a test to see the exact validation.error details","Relax or update the outputSchema if the new shape is the intended contract","Handle failure paths explicitly so the tool never returns null/undefined for a schema-required field"],"exampleFix":"// before\nasync run(args) { return (await api.getData()).data; }\n// after\nasync run(args) {\n  const { data } = await api.getData();\n  return outputSchema.parse({ items: data.items ?? [], total: data.total ?? 0 });\n}","handlingStrategy":"validation","validationCode":"const parsed = outputSchema.safeParse(result);\nif (!parsed.success) {\n  throw new Error(`Tool result invalid: ${parsed.error.message}`);\n}\nreturn parsed.data;","typeGuard":"function matchesOutputSchema(result: unknown, schema: z.ZodTypeAny): result is z.infer<typeof schema> {\n  return schema.safeParse(result).success;\n}","tryCatchPattern":"try {\n  const res = await client.callTool({ name, arguments });\n  return res;\n} catch (e) {\n  if (e.code === ErrorCode.InternalError && /outputSchema/.test(e.message)) {\n    console.error('Server tool returned schema-violating result:', e.message);\n  }\n  throw e;\n}","preventionTips":["Parse tool return values with outputSchema.parse inside the tool before returning","Add unit tests asserting tool output against its declared schema","Never return null/undefined on failure paths for schema-required fields","Update outputSchema whenever the tool's contract changes"],"tags":["mcp","zod","schema-validation","tools"],"backgroundTag":"schema-validation-failed","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}