diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/NullableIndex.java b/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/NullableIndex.java index 3d675a8e16b..aee20f29215 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/NullableIndex.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/NullableIndex.java @@ -179,8 +179,9 @@ public boolean isMemberNullable(MemberShape member, CheckMode checkMode) { } // fall-through. case LIST: - // Map values and list members are only null if they have the @sparse trait. - return container.hasTrait(SparseTrait.ID); + // Map values and list members are only null if they have the @sparse trait + // OR if the target is a Document since Document can hold a null value + return container.hasTrait(SparseTrait.ID) || target.isDocumentShape(); default: return false; } diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/validation/NodeValidationVisitorTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/validation/NodeValidationVisitorTest.java index 1d7ee51bacc..97b0262e388 100644 --- a/smithy-model/src/test/java/software/amazon/smithy/model/validation/NodeValidationVisitorTest.java +++ b/smithy-model/src/test/java/software/amazon/smithy/model/validation/NodeValidationVisitorTest.java @@ -675,6 +675,24 @@ public void nullNonSparseMapValue() { "a: Non-sparse map shape `ns.foo#Map` cannot contain null values")); } + @Test + public void nullNonSparseDocumentMapValue() { + // This should not raise any errors since null is a valid Document value + ObjectNode map = ObjectNode.builder() + .withMember("a", Node.nullNode()) + .build(); + NodeValidationVisitor visitor = NodeValidationVisitor.builder() + .value(map) + .model(MODEL) + .allowOptionalNull(true) + .build(); + List events = MODEL + .expectShape(ShapeId.from("ns.foo#DocumentMap")) + .accept(visitor); + + assertThat(events, hasSize(0)); + } + @Test public void nullSparseMapValue() { ObjectNode map = ObjectNode.builder() diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/validation/node-validator.json b/smithy-model/src/test/resources/software/amazon/smithy/model/validation/node-validator.json index 753bc144e57..0fc6576140a 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/validation/node-validator.json +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/validation/node-validator.json @@ -207,6 +207,15 @@ "smithy.api#sparse": {} } }, + "ns.foo#DocumentMap": { + "type": "map", + "key": { + "target": "ns.foo#KeyString" + }, + "value": { + "target": "smithy.api#Document" + } + }, "ns.foo#Structure": { "type": "structure", "members": {