Skip to content

fix(plugin-mcp): add error handling to convertCollectionSchemaToZod#16114

Merged
DanRibbens merged 1 commit into
payloadcms:mainfrom
ShaunMWallace:fix/mcp-plugin-schema-conversion-crash
Apr 1, 2026
Merged

fix(plugin-mcp): add error handling to convertCollectionSchemaToZod#16114
DanRibbens merged 1 commit into
payloadcms:mainfrom
ShaunMWallace:fix/mcp-plugin-schema-conversion-crash

Conversation

@ShaunMWallace

Copy link
Copy Markdown
Contributor

Summary

Wraps convertCollectionSchemaToZod in a try/catch so that a single collection's schema conversion failure doesn't crash the entire tools/list MCP response.

Problem

The schema conversion pipeline (JSON Schema → json-schema-to-zod → TypeScript transpile → eval) can fail for collections with complex nested schemas. When it does, the error propagates up to the MCP SDK's tools/list handler, crashing the entire response and making all MCP tools inaccessible — not just the one with the problematic schema.

The most common trigger is a Zod v4 bug where toJSONSchema crashes with TypeError: Cannot read properties of undefined (reading '_zod') on record schemas with undefined valueType (see colinhacks/zod#5821, PR colinhacks/zod#5822).

Fix

try {
  // existing conversion pipeline...
  return new Function('z', `return ${transpileResult.outputText}`)(z)
} catch (error) {
  console.warn(`[plugin-mcp] Schema conversion failed, using permissive fallback:`, error.message)
  return z.record(z.any())
}

When conversion fails:

  • The tool is still listed in tools/list (with a permissive z.record(z.any()) schema)
  • Other tools with valid schemas are completely unaffected
  • A warning is logged to help diagnose which collections have problematic schemas

Impact

Without this fix, any project with 20+ collections (where at least one has a complex nested block schema) will have a completely non-functional MCP server — tools/list returns an error instead of the tool list. With this fix, only the affected collection loses strict parameter validation; everything else works normally.

Testing

Verified in production with a 22-collection Payload CMS deployment on Vercel. Before the fix, tools/list crashed entirely. After, all tools are listed and functional.

The schema conversion pipeline (JSON Schema → Zod string → TypeScript
transpile → eval) can fail for collections with complex nested schemas,
particularly when Zod v4's toJSONSchema encounters record schemas with
undefined valueType (see colinhacks/zod#5821).

Without this catch, a single collection's schema failure crashes the
entire tools/list response, making all MCP tools inaccessible.

This wraps the conversion in try/catch and falls back to z.record(z.any())
so the tool is still listed (with permissive validation) while other tools
with valid schemas remain unaffected.
@DanRibbens DanRibbens merged commit 6184b0c into payloadcms:main Apr 1, 2026
160 checks passed
@github-actions

github-actions Bot commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

🚀 This is included in version v3.82.0

milamer pushed a commit to milamer/payload that referenced this pull request Apr 20, 2026
…ayloadcms#16114)

## Summary

Wraps `convertCollectionSchemaToZod` in a try/catch so that a single
collection's schema conversion failure doesn't crash the entire
`tools/list` MCP response.

## Problem

The schema conversion pipeline (`JSON Schema → json-schema-to-zod →
TypeScript transpile → eval`) can fail for collections with complex
nested schemas. When it does, the error propagates up to the MCP SDK's
`tools/list` handler, crashing the entire response and making **all**
MCP tools inaccessible — not just the one with the problematic schema.

The most common trigger is a Zod v4 bug where `toJSONSchema` crashes
with `TypeError: Cannot read properties of undefined (reading '_zod')`
on record schemas with undefined `valueType` (see
[colinhacks/zod#5821](colinhacks/zod#5821), PR
[colinhacks/zod#5822](colinhacks/zod#5822)).

## Fix

```typescript
try {
  // existing conversion pipeline...
  return new Function('z', `return ${transpileResult.outputText}`)(z)
} catch (error) {
  console.warn(`[plugin-mcp] Schema conversion failed, using permissive fallback:`, error.message)
  return z.record(z.any())
}
```

When conversion fails:
- The tool is still listed in `tools/list` (with a permissive
`z.record(z.any())` schema)
- Other tools with valid schemas are completely unaffected
- A warning is logged to help diagnose which collections have
problematic schemas

## Impact

Without this fix, any project with 20+ collections (where at least one
has a complex nested block schema) will have a completely non-functional
MCP server — `tools/list` returns an error instead of the tool list.
With this fix, only the affected collection loses strict parameter
validation; everything else works normally.

## Testing

Verified in production with a 22-collection Payload CMS deployment on
Vercel. Before the fix, `tools/list` crashed entirely. After, all tools
are listed and functional.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants