RegisteredTool.update() crashes with ZodObject inputSchema (passthrough schemas)

Aperta Adatta ai principianti
#1,960 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
76/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
typescript
Ambito
api

Direzione di ricerca

Inizia con il percorso di aggiornamento di _createRegisteredTool, getZodSchemaObject() e objectFromShape(), confrontando il comportamento dell’aggiornamento con il percorso di creazione. Riproduci il problema usando l’esempio di passthrough ZodObject, quindi verifica che l’aggiornamento di paramsSchema funzioni sia per le istanze di ZodObject sia per gli raw shapes, senza l’errore null _zod.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug fix proposed good first issue P2

Description

RegisteredTool.update() crashes when paramsSchema is a ZodObject instance (e.g. z.object({...}).passthrough()) instead of a raw shape (Record<string, ZodType>).

The error:

TypeError: Cannot read properties of null (reading '_zod')

Root cause

The create path in _createRegisteredTool uses getZodSchemaObject(inputSchema) which correctly handles both raw shapes and ZodObject instances:

function getZodSchemaObject(schema) {
    if (!schema) return undefined;
    if (isZodRawShapeCompat(schema)) return objectFromShape(schema); // raw shape
    return schema; // ZodObject — pass through
}

But the update path calls objectFromShape() directly:

update: updates => {
    if (typeof updates.paramsSchema !== 'undefined')
        registeredTool.inputSchema = objectFromShape(updates.paramsSchema);
}

objectFromShape expects a raw shape and calls Object.values(shape). When given a Zod v3 ZodObject, Object.values() iterates all own enumerable properties — including internal ones like _cached which is null. This leads to isZ4Schema(null) which accesses null._zod and throws.

Type inconsistency

The types reflect the same inconsistency:

  • registerTool accepts inputSchema?: InputArgs where InputArgs extends undefined | ZodRawShapeCompat | AnySchema — ZodObject is supported
  • RegisteredTool.update() types paramsSchema?: InputArgs where InputArgs extends ZodRawShapeCompat — only raw shapes

Reproduction

const { z } = require('zod');

const schema = z.object({
    id: z.string(),
    property: z.string().optional(),
}).passthrough();

// Register works fine (create path handles ZodObject)
const tool = server.registerTool('my_tool', {
    description: 'test',
    inputSchema: schema,
}, async (args) => ({ content: [{ type: 'text', text: 'ok' }] }));

// Update crashes (update path does not handle ZodObject)
tool.update({ paramsSchema: schema });
// TypeError: Cannot read properties of null (reading '_zod')

Suggested fix

The update path should use getZodSchemaObject() (or equivalent) instead of calling objectFromShape() directly, matching the create path behavior.

Environment

  • @modelcontextprotocol/sdk: 1.26.0
  • zod: 3.25.76
  • Node.js: v20.x
Lingua principale
TypeScript
Stelle
13.4k
Fork
2.2k
Merge medio
3g 12h
PR unite (30g)
3

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di modelcontextprotocol/typescript-sdk

Tutte le issue di modelcontextprotocol/typescript-sdk

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.