解决使用allOf与additionalProperties:false的Swagger Schema验证问题
allOf + additionalProperties: false Validation Conflict in Swagger Schema The root of your problem is how AJV handles allOf with additionalProperties: false on each subschema: when validating against an allOf schema, AJV runs validation against each subschema individually. So your first subschema (with contact fields) flags address-related fields as extra, and your address subschema flags contact fields as extra—hence the 6 errors.
Here's the cleanest fix that preserves both your validation goals (restricting extra properties overall, and keeping the address schema usable standalone):
Step 1: Extract a reusable "core" address schema
First, create a base schema for address properties without the additionalProperties: false restriction. This lets us reuse the address fields without conflicting in combined schemas.
Step 2: Update address schema for standalone use
Reference the core address schema and add additionalProperties: false here—so when address is used alone, it still blocks extra fields.
Step 3: Fix deliveryContact schema
Combine the contact properties and core address schema, then add additionalProperties: false at the top level of deliveryContact. This way, AJV merges all allowed properties first, then checks for extras once, instead of per-subschema.
Here's the modified code:
"definitions": { "addressCore": { "type": "object", "properties": { "address": { "type": "string", "maxLength": 1024 }, "postalCode": { "type": "string", "maxLength": 12 }, "city": { "type": "string", "maxLength": 512 }, "state": { "type": "string", "maxLength": 512 } } }, "address": { "allOf": [{"$ref": "#/definitions/addressCore"}], "additionalProperties": false }, "deliveryContact": { "type": "object", "additionalProperties": false, "allOf": [ { "type": "object", "properties": { "name": { "type": "string", "maxLength": 1024 }, "phone": { "type": "string", "maxLength": 24 } } }, {"$ref": "#/definitions/addressCore"} ] } }
Why this works:
- When validating
deliveryContact, AJV merges the contact properties andaddressCoreproperties into a single set of allowed fields. The top-leveladditionalProperties: falsethen checks if any fields in your test data fall outside this combined set (none do, in your case). - When using the
addressschema alone, it still enforcesadditionalProperties: falseto block extra fields likenameorphone.
If you don't need the address schema to be usable standalone, you could simplify further by removing the addressCore and just merging the properties directly in deliveryContact with a top-level additionalProperties: false, but the above approach keeps your schemas modular.
内容的提问来源于stack exchange,提问作者Mathieu Gobert

