Skip to content

Commit cdbeeaf

Browse files
committed
fix: improve Zod v4 optional schema detection
- Prioritize `isOptional()` method check in isSchemaOptional to support both Zod v3 and v4 consistently. - Add `typeName` check for Zod v4 internal definitions to correctly identify optional schemas. - Fixes an issue where optional tool arguments were incorrectly marked as required in the generated JSON schema.
1 parent 2d2c8ff commit cdbeeaf

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

src/server/zod-compat.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export interface ZodV4Internal {
3232
_zod?: {
3333
def?: {
3434
type?: string;
35+
typeName?: string;
3536
value?: unknown;
3637
values?: unknown[];
3738
shape?: Record<string, AnySchema> | (() => Record<string, AnySchema>);
@@ -236,15 +237,16 @@ export function getSchemaDescription(schema: AnySchema): string | undefined {
236237
* Works with both Zod v3 and v4.
237238
*/
238239
export function isSchemaOptional(schema: AnySchema): boolean {
240+
// Check for isOptional method first (works for both v3 and v4 usually)
241+
if (typeof (schema as { isOptional?: () => boolean }).isOptional === 'function') {
242+
return (schema as { isOptional: () => boolean }).isOptional();
243+
}
244+
239245
if (isZ4Schema(schema)) {
240246
const v4Schema = schema as unknown as ZodV4Internal;
241-
return v4Schema._zod?.def?.type === 'optional';
247+
return v4Schema._zod?.def?.type === 'optional' || v4Schema._zod?.def?.typeName === 'ZodOptional';
242248
}
243249
const v3Schema = schema as unknown as ZodV3Internal;
244-
// v3 has isOptional() method
245-
if (typeof (schema as { isOptional?: () => boolean }).isOptional === 'function') {
246-
return (schema as { isOptional: () => boolean }).isOptional();
247-
}
248250
return v3Schema._def?.typeName === 'ZodOptional';
249251
}
250252

0 commit comments

Comments
 (0)