You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSON Schema oneOf校验报错:数据匹配多个子Schema问题排查

问题:JSON Schema oneOf验证失败,提示多个schema匹配

验证DRUGTREATMENT类型数据时触发错误:

should be valid to one and only one of schema, but more than one are valid: {"$ref":"#/$defs/drug-treatment"}{"$ref":"#/$defs/surgery-treatment"}

原Schema定义

{
  "$id": "someid",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "JSON Schema for treatments",
  "oneOf" : [
    { "$ref" : "#/$defs/drug-treatment" },
    { "$ref" : "#/$defs/surgery-treatment" }
  ],
  "$defs": {
    "base": {
      "type": "object",
      "properties": {
        "type-tag": {
          "enum": [ "SURGERY", "DRUGTREATMENT", "RADIOLOGY", "PHYSIOTHERAPY" ]
        },
        "id": {
          "type": "string",
          "format": "uuid"
        },
        "patient-id": {
          "type": "string",
          "format": "uuid"
        },
        "patient-name": {
          "type": "string"
        },
        "provider-id": {
          "type": "string",
          "format": "uuid"
        },
        "provider-name": {
          "type": "string"
        },
        "diagnosis": {
          "type": "string"
        },
        "followup-treatments": {
          "type" : "array",
          "items" : { "$ref" : "#" }
        }
      },
      "required": [
        "id",
        "type-tag",
        "patient-id",
        "patient-name",
        "provider-id",
        "provider-name",
        "diagnosis",
        "followup-treatments"
      ]
    },
    "drug-treatment": {
      "allOf": [
        { "$ref" : "#/$defs/base" }
      ],
      "properties": {
        "drug": {
          "type": "string"
        },
        "dosage": {
          "type": "number"
        },
        "start-date": {
          "type": "string",
          "format": "date"
        },
        "end-date": {
          "type": "string",
          "format": "date"
        },
        "frequency": "integer"
      },
      "required": [
        "drug",
        "dosage",
        "start-date",
        "end-date",
        "frequency"
      ],
      "unevaluatedProperties" : false
    },
    "surgery-treatment": {
      "allOf": [
        { "$ref" : "#/$defs/base" }
      ],
      "properties": {
        "surgery-date": {
          "type": "string",
          "format": "date"
        },
        "discharge-instructions": {
          "type": "string"
        },
        "required": [
          "surgery-date",
          "discharge-instructions"
        ],
        "unevaluatedProperties" : false
      }
    },
  }
}

示例验证数据

"treatments": [
    {
      "type-tag": "DRUGTREATMENT",
      "drug": "fdsds",
      "dosage": 2.0,
      "start-date": "2222-02-12",
      "end-date": "2222-02-12",
      "frequency": 2,
      "id": "aa7da984-0252-45b1-b0cd-f1dbe98662e2",
      "patient-id": "ab62420e-0bd8-4e39-8e0b-36e464b7abb2",
      "patient-name": "Tom",
      "provider-id": "154523b2-7598-4ed4-aab1-b2ef1692109c",
      "provider-name": "gdsfdsd",
      "diagnosis": "sfdsfds",
      "followup-treatments": []
    },
    {
      "type-tag": "SURGERY",
      "surgery-date": "2222-02-12",
      "discharge-instructions": "dsfdsfdsfds",
      "id": "12d2e565-8966-4029-840b-1959277b37f6",
      "patient-id": "ab62420e-0bd8-4e39-8e0b-36e464b7abb2",
      "patient-name": "Tom",
      "provider-id": "154523b2-7598-4ed4-aab1-b2ef1692109c",
      "provider-name": "gdsfdsd",
      "diagnosis": "fdsfds",
      "followup-treatments": [],
    }
  ]

问题根源

  1. surgery-treatment结构错误:required和unevaluatedProperties被错误嵌套在properties字段内部,导致这两个约束完全不生效。此时surgery-treatment仅继承base的规则,没有自身的必填字段校验,也不限制额外属性。
  2. 子Schema无互斥性:DRUGTREATMENT类型的数据既满足drug-treatment的所有规则,又因为surgery-treatment的约束失效,只要符合base规则就会被通过,最终同时匹配两个schema,触发oneOf的“只能匹配一个”校验错误。

修复后的Schema

{
  "$id": "someid",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "JSON Schema for treatments",
  "oneOf" : [
    { "$ref" : "#/$defs/drug-treatment" },
    { "$ref" : "#/$defs/surgery-treatment" }
  ],
  "$defs": {
    "base": {
      "type": "object",
      "properties": {
        "type-tag": {
          "enum": [ "SURGERY", "DRUGTREATMENT", "RADIOLOGY", "PHYSIOTHERAPY" ]
        },
        "id": {
          "type": "string",
          "format": "uuid"
        },
        "patient-id": {
          "type": "string",
          "format": "uuid"
        },
        "patient-name": {
          "type": "string"
        },
        "provider-id": {
          "type": "string",
          "format": "uuid"
        },
        "provider-name": {
          "type": "string"
        },
        "diagnosis": {
          "type": "string"
        },
        "followup-treatments": {
          "type" : "array",
          "items" : { "$ref" : "#" }
        }
      },
      "required": [
        "id",
        "type-tag",
        "patient-id",
        "patient-name",
        "provider-id",
        "provider-name",
        "diagnosis",
        "followup-treatments"
      ]
    },
    "drug-treatment": {
      "allOf": [
        { "$ref" : "#/$defs/base" }
      ],
      "properties": {
        "drug": {
          "type": "string"
        },
        "dosage": {
          "type": "number"
        },
        "start-date": {
          "type": "string",
          "format": "date"
        },
        "end-date": {
          "type": "string",
          "format": "date"
        },
        "frequency": { "type": "integer" }
      },
      "required": [
        "drug",
        "dosage",
        "start-date",
        "end-date",
        "frequency"
      ],
      "unevaluatedProperties" : false
    },
    "surgery-treatment": {
      "allOf": [
        { "$ref" : "#/$defs/base" }
      ],
      "properties": {
        "surgery-date": {
          "type": "string",
          "format": "date"
        },
        "discharge-instructions": {
          "type": "string"
        }
      },
      "required": [
        "surgery-date",
        "discharge-instructions"
      ],
      "unevaluatedProperties" : false
    }
  }
}

关键修复点

  • 将surgery-treatment的required和unevaluatedProperties从properties内部移到外部,让约束生效
  • 修正drug-treatment中frequency字段的错误写法,从"frequency": "integer"改为"frequency": { "type": "integer" }
  • 移除Schema末尾多余的逗号,避免JSON解析错误

修复原理

修复后,surgery-treatment会校验surgery-date和discharge-instructions是否存在,DRUGTREATMENT类型的数据因缺少这两个字段,会被surgery-treatment拒绝,最终仅匹配drug-treatment一个schema,满足oneOf的校验要求。同时unevaluatedProperties: false会限制每个子类型只能拥有自身定义的属性,彻底避免跨类型误匹配。

内容的提问来源于stack exchange,提问作者Dilantha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 13:51:30