含不同对象类型数组的JSON Schema未触发必填项校验问题排查
JSON Schema校验未触发必填字段警告的原因排查
我修改了原始Schema复现实际问题,当前使用的主JSON Schema、引用的clone.json Schema如下,测试JSON中clone和build字段均为空对象,但VSCode未触发必填参数缺失的警告,现排查问题原因。
主JSON Schema
{ "type": "object", "properties": { "stages": { "type": "array", "minItems": 1, "items": { "anyOf": [ {"$ref": "clone.json#/clone"}, {"$ref": "clone.json#/build"} ] } } } }
引用的clone.json Schema
{ "proper": { "type": "object", "additionalProperties": false, "properties": { "name1": {"type": "string"}, "name2": {"type": "string"} }, "required": ["name2"] }, "clone": { "type": "object", "additionalProperties": false, "properties": { "clone": { "anyOf": [ { "$ref": "#/proper" }, { "type": "object", "additionalProperties": false, "properties": { "cloneName": { "description": "The repo name", "type": "string" } }, "required": [ "cloneName" ] } ] } } }, "build": { "type": "object", "properties": { "build": { "anyOf": [ { "$ref": "#/proper" }, { "type": "object", "additionalProperties": false, "properties": { "buildName": { "description": "The repo name", "type": "string" } }, "required": [ "buildName" ] } ] } } } }
测试JSON
{ "stages": [ { "clone": {} }, { "build": {} } ] }
问题原因分析
1. {"clone": {}}无警告的原因
主Schema的stages.items使用anyOf逻辑,只要匹配其中一个子Schema即判定有效:
{"clone": {}}不符合cloneSchema:因为clone字段的值是空对象,不满足其内部anyOf的两个规则(要么含name2,要么含cloneName);- 但
{"clone": {}}符合buildSchema:buildSchema未设置additionalProperties: false,默认允许任意额外字段,且不要求必须包含build字段,因此该对象被判定为合法的build实例,anyOf匹配成功,无警告。
2. {"build": {}}无警告的原因
{"build": {}}不符合cloneSchema:cloneSchema设置了additionalProperties: false,仅允许clone字段,存在build字段属于非法额外字段;- 但VSCode未触发警告的核心原因是:
buildSchema未设置additionalProperties: false,且未将build字段设为必填。此时校验器将{"build": {}}视为“不含合法build字段的普通对象”,而buildSchema允许这种情况(因为build字段非必填),因此误判为有效。
解决方案
- 给
buildSchema添加additionalProperties: false,禁止额外字段,确保{"clone": {}}无法匹配buildSchema; - 给
clone和buildSchema分别添加required: ["clone"]和required: ["build"],强制要求必须包含对应字段,触发内部字段的必填校验; - 将主Schema的
anyOf替换为oneOf,确保每个阶段只能属于clone或build中的一种,避免模糊匹配。
内容的提问来源于stack exchange,提问作者Chaim Nachmani
相关产品推荐
相关产品推荐

