Skip to content

Commit 14b093e

Browse files
committed
fix(core): reject Standard Schema failures with empty issues
1 parent b415e60 commit 14b093e

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@modelcontextprotocol/client': patch
3+
'@modelcontextprotocol/server': patch
4+
---
5+
6+
Treat Standard Schema validation results with an empty `issues` array as failures instead of accepting an undefined value.

‎packages/core-internal/src/util/standardSchema.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ export async function validateStandardSchema<T extends StandardSchemaV1>(
284284
data: unknown
285285
): Promise<StandardSchemaValidationResult<StandardSchemaV1.InferOutput<T>>> {
286286
const result = await schema['~standard'].validate(data);
287-
if (result.issues && result.issues.length > 0) {
287+
if (result.issues) {
288288
return { success: false, error: result.issues.map(i => formatIssue(i)).join(', ') };
289289
}
290290
return { success: true, data: (result as StandardSchemaV1.SuccessResult<unknown>).value as StandardSchemaV1.InferOutput<T> };

‎packages/core-internal/test/util/standardSchema.test.ts‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
11
import * as z from 'zod/v4';
22

3-
import { standardSchemaToJsonSchema } from '../../src/util/standardSchema';
3+
import { type StandardSchemaV1, standardSchemaToJsonSchema, validateStandardSchema } from '../../src/util/standardSchema';
4+
5+
describe('validateStandardSchema', () => {
6+
test.each(['synchronous', 'asynchronous'] as const)('rejects %s failures with an empty issues array', async mode => {
7+
const schema: StandardSchemaV1 = {
8+
'~standard': {
9+
version: 1,
10+
vendor: 'empty-issues',
11+
validate: () => (mode === 'asynchronous' ? Promise.resolve({ issues: [] }) : { issues: [] })
12+
}
13+
};
14+
15+
await expect(validateStandardSchema(schema, { name: 'example' })).resolves.toEqual({ success: false, error: '' });
16+
});
17+
18+
test('preserves transformed values when validation succeeds', async () => {
19+
const schema = z.string().transform(value => value.toUpperCase());
20+
21+
await expect(validateStandardSchema(schema, 'hello')).resolves.toEqual({ success: true, data: 'HELLO' });
22+
});
23+
24+
test('preserves undefined when validation succeeds', async () => {
25+
await expect(validateStandardSchema(z.undefined(), undefined)).resolves.toEqual({ success: true, data: undefined });
26+
});
27+
});
428

529
describe('standardSchemaToJsonSchema', () => {
630
test('emits type:object for plain z.object schemas', () => {

0 commit comments

Comments
 (0)