From 29c620709dc60c932b382d022f4506925e17a8c8 Mon Sep 17 00:00:00 2001 From: Jachym Metlicka Date: Fri, 26 Jun 2026 17:57:45 +0200 Subject: [PATCH 01/19] fix: normalize OAS 3.1 schemas with type:[object,"null"] to set nullable:true correctly --- .../codegen/OpenAPINormalizer.java | 6 +++- .../codegen/OpenAPINormalizerTest.java | 29 +++++++++++++++++ .../spring/KotlinSpringServerCodegenTest.java | 31 +++++++++++++++++++ .../src/test/resources/3_1/issue_24139.yaml | 31 +++++++++++++++++++ 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index f2909042bbba..64009e830628 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,7 +980,11 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - normalizeProperties(schema, visitedSchemas); + // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema + // before processing its properties, so that nullable:true is set correctly. + Schema result = processNormalize31Spec(schema, visitedSchemas); + normalizeProperties(result, visitedSchemas); + return result; } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index 53cacea15650..e23364828b52 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1896,4 +1896,33 @@ public void testLooseNullDefinitions() { ModelUtils.looseNullDefinitions = false; } + /** + * Verify that a schema defined as type:[object,"null"] WITH properties (OAS 3.1 style) + * is correctly normalized so that nullable:true is set on the schema itself. + * Regression test for https://github.com/OpenAPITools/openapi-generator/issues/24139 + */ + @Test + public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); + + // Before normalization: NestedNullable has types=[object,null], nullable is not yet set + Schema nestedNullableBefore = openAPI.getComponents().getSchemas().get("NestedNullable"); + assertNotNull(nestedNullableBefore); + assertNotNull(nestedNullableBefore.getProperties()); + + Map options = new HashMap<>(); + options.put("NORMALIZE_31SPEC", "true"); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); + openAPINormalizer.normalize(); + + // After normalization: nullable must be true and type must be "object" + Schema nestedNullableAfter = openAPI.getComponents().getSchemas().get("NestedNullable"); + assertNotNull(nestedNullableAfter); + assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, + "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); + assertEquals(nestedNullableAfter.getType(), "object"); + assertNotNull(nestedNullableAfter.getProperties()); + } + } + diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java index 7fbc5ceea289..f7f06fd68429 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java @@ -6813,4 +6813,35 @@ public void paramJsonPropertyAnnotationWithDigitStartingPropertyName() throws IO "@param:JsonProperty(\"2nd_field\")\n @get:JsonProperty(\"2nd_field\") val `2ndField`" ); } + + /** + * Regression test for https://github.com/OpenAPITools/openapi-generator/issues/24139 + * A property that $ref's an OAS 3.1 schema with type:[object,"null"] is nullable and must + * NOT receive @field:JsonSetter(nulls = Nulls.FAIL). + */ + @Test(description = "issue 24139: nullable $ref (type:[object,null]) must not get @JsonSetter(nulls = Nulls.FAIL)") + public void testIssue24139NullableRefNoJsonSetterNullsFail() throws IOException { + Map additionalProperties = new HashMap<>(); + additionalProperties.put("useBeanValidation", true); + additionalProperties.put("openApiNullable", "true"); + + Map files = generateFromContract( + "src/test/resources/3_1/issue_24139.yaml", + additionalProperties + ); + + File itemFile = files.get("Item.kt"); + assertThat(itemFile).isNotNull(); + + // nestedNullable: $ref to NestedNullable (type:[object,"null"]) — nullable, no @JsonSetter(nulls = Nulls.FAIL) + assertFileNotContains(itemFile.toPath(), "nestedNullable: NestedNullable"); + // The field must NOT have @JsonSetter(nulls = Nulls.FAIL) because the referenced schema is nullable + String content = org.apache.commons.io.FileUtils.readFileToString(itemFile, StandardCharsets.UTF_8); + // Extract the nestedNullable field block and verify annotation absence + Assert.assertFalse( + content.contains("@field:JsonSetter(nulls = Nulls.FAIL)\n @param:JsonProperty(\"nestedNullable\")") || + content.contains("@field:JsonSetter(nulls = Nulls.FAIL)\n @get:JsonProperty(\"nestedNullable\")"), + "nestedNullable ($ref to nullable schema) must not have @JsonSetter(nulls = Nulls.FAIL)" + ); + } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml new file mode 100644 index 000000000000..57b172a507c2 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -0,0 +1,31 @@ +openapi: 3.1.1 +info: + title: Test issue 24139 + version: 1.0.0 + +components: + schemas: + NestedNullable: + type: [ object, "null" ] + properties: + value: + type: [ number, "null" ] + Nested: + type: object + properties: + value: + type: [ number, "null" ] + + Item: + type: object + properties: + nestedNullable: + $ref: '#/components/schemas/NestedNullable' + + nestedNullable2: + anyOf: + - $ref: '#/components/schemas/Nested' + - type: 'null' + + nested: + $ref: '#/components/schemas/Nested' From cb5aa4917299ccce88cb1867e8e646f0bf2651ae Mon Sep 17 00:00:00 2001 From: Jachym Metlicka Date: Fri, 26 Jun 2026 18:05:21 +0200 Subject: [PATCH 02/19] fix: ensure OAS 3.1 schemas with type array including "null" set nullable:true correctly and preserve properties --- .../codegen/OpenAPINormalizer.java | 18 ++++++++--- .../codegen/OpenAPINormalizerTest.java | 31 ++++++++++++++++++- .../src/test/resources/3_1/issue_24139.yaml | 6 ++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index 64009e830628..f79dc954e119 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,11 +980,19 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema - // before processing its properties, so that nullable:true is set correctly. - Schema result = processNormalize31Spec(schema, visitedSchemas); - normalizeProperties(result, visitedSchemas); - return result; + // OAS 3.1: if the type array includes "null", extract it and set nullable:true + // on the parent schema before normalizing its child properties. + // We intentionally do NOT call the full processNormalize31Spec here because + // that method can replace a JsonSchema with properties (but no explicit type) + // with an empty schema, discarding all properties. + if (getRule(NORMALIZE_31SPEC) && schema.getTypes() != null && schema.getTypes().contains("null")) { + schema.setNullable(true); + schema.getTypes().remove("null"); + if (schema.getTypes().size() == 1) { + schema.setType(String.valueOf(schema.getTypes().iterator().next())); + } + } + normalizeProperties(schema, visitedSchemas); } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index e23364828b52..a512e736e29e 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1921,7 +1921,36 @@ public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); assertEquals(nestedNullableAfter.getType(), "object"); - assertNotNull(nestedNullableAfter.getProperties()); + assertNotNull(nestedNullableAfter.getProperties(), + "NestedNullable properties must be preserved after normalization"); + } + + /** + * Regression test: an OAS 3.1 schema with properties but NO explicit type declaration + * must keep its properties after NORMALIZE_31SPEC normalization. + * Regression for a potential regression introduced by the fix for issue 24139. + */ + @Test + public void testIssue24139ImpliedObjectSchemaKeepsProperties() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); + + Schema impliedBefore = openAPI.getComponents().getSchemas().get("ImpliedObject"); + assertNotNull(impliedBefore); + assertNotNull(impliedBefore.getProperties()); + + Map options = new HashMap<>(); + options.put("NORMALIZE_31SPEC", "true"); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); + openAPINormalizer.normalize(); + + Schema impliedAfter = openAPI.getComponents().getSchemas().get("ImpliedObject"); + assertNotNull(impliedAfter); + assertNotNull(impliedAfter.getProperties(), + "ImpliedObject (no explicit type, just properties) must keep its properties after normalization"); + assertNotNull(impliedAfter.getProperties().get("name"), + "ImpliedObject.name property must be preserved after normalization"); + assertNull(impliedAfter.getNullable(), + "ImpliedObject must not be marked nullable (no null type was declared)"); } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml index 57b172a507c2..69910a01bb06 100644 --- a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -15,6 +15,12 @@ components: properties: value: type: [ number, "null" ] + # OAS 3.1 allows object schemas with properties but no explicit type declaration. + # This must not lose its properties after normalization. + ImpliedObject: + properties: + name: + type: string Item: type: object From b0d188d9c44f8e653e15acf9b5bced72f0b7fa38 Mon Sep 17 00:00:00 2001 From: Jachym Metlicka Date: Fri, 26 Jun 2026 18:19:47 +0200 Subject: [PATCH 03/19] Revert "fix: ensure OAS 3.1 schemas with type array including "null" set nullable:true correctly and preserve properties" This reverts commit cb5aa4917299ccce88cb1867e8e646f0bf2651ae. --- .../codegen/OpenAPINormalizer.java | 18 +++-------- .../codegen/OpenAPINormalizerTest.java | 31 +------------------ .../src/test/resources/3_1/issue_24139.yaml | 6 ---- 3 files changed, 6 insertions(+), 49 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index f79dc954e119..64009e830628 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,19 +980,11 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - // OAS 3.1: if the type array includes "null", extract it and set nullable:true - // on the parent schema before normalizing its child properties. - // We intentionally do NOT call the full processNormalize31Spec here because - // that method can replace a JsonSchema with properties (but no explicit type) - // with an empty schema, discarding all properties. - if (getRule(NORMALIZE_31SPEC) && schema.getTypes() != null && schema.getTypes().contains("null")) { - schema.setNullable(true); - schema.getTypes().remove("null"); - if (schema.getTypes().size() == 1) { - schema.setType(String.valueOf(schema.getTypes().iterator().next())); - } - } - normalizeProperties(schema, visitedSchemas); + // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema + // before processing its properties, so that nullable:true is set correctly. + Schema result = processNormalize31Spec(schema, visitedSchemas); + normalizeProperties(result, visitedSchemas); + return result; } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index a512e736e29e..e23364828b52 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1921,36 +1921,7 @@ public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); assertEquals(nestedNullableAfter.getType(), "object"); - assertNotNull(nestedNullableAfter.getProperties(), - "NestedNullable properties must be preserved after normalization"); - } - - /** - * Regression test: an OAS 3.1 schema with properties but NO explicit type declaration - * must keep its properties after NORMALIZE_31SPEC normalization. - * Regression for a potential regression introduced by the fix for issue 24139. - */ - @Test - public void testIssue24139ImpliedObjectSchemaKeepsProperties() { - OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); - - Schema impliedBefore = openAPI.getComponents().getSchemas().get("ImpliedObject"); - assertNotNull(impliedBefore); - assertNotNull(impliedBefore.getProperties()); - - Map options = new HashMap<>(); - options.put("NORMALIZE_31SPEC", "true"); - OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); - openAPINormalizer.normalize(); - - Schema impliedAfter = openAPI.getComponents().getSchemas().get("ImpliedObject"); - assertNotNull(impliedAfter); - assertNotNull(impliedAfter.getProperties(), - "ImpliedObject (no explicit type, just properties) must keep its properties after normalization"); - assertNotNull(impliedAfter.getProperties().get("name"), - "ImpliedObject.name property must be preserved after normalization"); - assertNull(impliedAfter.getNullable(), - "ImpliedObject must not be marked nullable (no null type was declared)"); + assertNotNull(nestedNullableAfter.getProperties()); } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml index 69910a01bb06..57b172a507c2 100644 --- a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -15,12 +15,6 @@ components: properties: value: type: [ number, "null" ] - # OAS 3.1 allows object schemas with properties but no explicit type declaration. - # This must not lose its properties after normalization. - ImpliedObject: - properties: - name: - type: string Item: type: object From 74eb333a3a551aff06c9353c0492616941f0c90d Mon Sep 17 00:00:00 2001 From: Jachym Metlicka Date: Fri, 26 Jun 2026 18:19:51 +0200 Subject: [PATCH 04/19] Reapply "fix: ensure OAS 3.1 schemas with type array including "null" set nullable:true correctly and preserve properties" This reverts commit b0d188d9c44f8e653e15acf9b5bced72f0b7fa38. --- .../codegen/OpenAPINormalizer.java | 18 ++++++++--- .../codegen/OpenAPINormalizerTest.java | 31 ++++++++++++++++++- .../src/test/resources/3_1/issue_24139.yaml | 6 ++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index 64009e830628..f79dc954e119 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,11 +980,19 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema - // before processing its properties, so that nullable:true is set correctly. - Schema result = processNormalize31Spec(schema, visitedSchemas); - normalizeProperties(result, visitedSchemas); - return result; + // OAS 3.1: if the type array includes "null", extract it and set nullable:true + // on the parent schema before normalizing its child properties. + // We intentionally do NOT call the full processNormalize31Spec here because + // that method can replace a JsonSchema with properties (but no explicit type) + // with an empty schema, discarding all properties. + if (getRule(NORMALIZE_31SPEC) && schema.getTypes() != null && schema.getTypes().contains("null")) { + schema.setNullable(true); + schema.getTypes().remove("null"); + if (schema.getTypes().size() == 1) { + schema.setType(String.valueOf(schema.getTypes().iterator().next())); + } + } + normalizeProperties(schema, visitedSchemas); } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index e23364828b52..a512e736e29e 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1921,7 +1921,36 @@ public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); assertEquals(nestedNullableAfter.getType(), "object"); - assertNotNull(nestedNullableAfter.getProperties()); + assertNotNull(nestedNullableAfter.getProperties(), + "NestedNullable properties must be preserved after normalization"); + } + + /** + * Regression test: an OAS 3.1 schema with properties but NO explicit type declaration + * must keep its properties after NORMALIZE_31SPEC normalization. + * Regression for a potential regression introduced by the fix for issue 24139. + */ + @Test + public void testIssue24139ImpliedObjectSchemaKeepsProperties() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); + + Schema impliedBefore = openAPI.getComponents().getSchemas().get("ImpliedObject"); + assertNotNull(impliedBefore); + assertNotNull(impliedBefore.getProperties()); + + Map options = new HashMap<>(); + options.put("NORMALIZE_31SPEC", "true"); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); + openAPINormalizer.normalize(); + + Schema impliedAfter = openAPI.getComponents().getSchemas().get("ImpliedObject"); + assertNotNull(impliedAfter); + assertNotNull(impliedAfter.getProperties(), + "ImpliedObject (no explicit type, just properties) must keep its properties after normalization"); + assertNotNull(impliedAfter.getProperties().get("name"), + "ImpliedObject.name property must be preserved after normalization"); + assertNull(impliedAfter.getNullable(), + "ImpliedObject must not be marked nullable (no null type was declared)"); } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml index 57b172a507c2..69910a01bb06 100644 --- a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -15,6 +15,12 @@ components: properties: value: type: [ number, "null" ] + # OAS 3.1 allows object schemas with properties but no explicit type declaration. + # This must not lose its properties after normalization. + ImpliedObject: + properties: + name: + type: string Item: type: object From 6a4bd103ecd3b98834816e9e94ad0f07bcd62762 Mon Sep 17 00:00:00 2001 From: Jachym Metlicka Date: Sat, 27 Jun 2026 14:55:07 +0200 Subject: [PATCH 05/19] add whitespace to retrigger tests --- .../codegen/kotlin/spring/KotlinSpringServerCodegenTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java index f7f06fd68429..fb53bafa3ad0 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java @@ -6814,6 +6814,7 @@ public void paramJsonPropertyAnnotationWithDigitStartingPropertyName() throws IO ); } + /** * Regression test for https://github.com/OpenAPITools/openapi-generator/issues/24139 * A property that $ref's an OAS 3.1 schema with type:[object,"null"] is nullable and must From 68e6dfffafcd0578de9cd370f00fd9a4dd2d222d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sat, 27 Jun 2026 15:20:03 +0200 Subject: [PATCH 06/19] Revert "add whitespace to retrigger tests" This reverts commit 6a4bd103ecd3b98834816e9e94ad0f07bcd62762. --- .../codegen/kotlin/spring/KotlinSpringServerCodegenTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java index fb53bafa3ad0..f7f06fd68429 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java @@ -6814,7 +6814,6 @@ public void paramJsonPropertyAnnotationWithDigitStartingPropertyName() throws IO ); } - /** * Regression test for https://github.com/OpenAPITools/openapi-generator/issues/24139 * A property that $ref's an OAS 3.1 schema with type:[object,"null"] is nullable and must From 7f0b9a6006ba58ba73b4e9aa33c6d0991ff8ea30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sat, 27 Jun 2026 15:20:07 +0200 Subject: [PATCH 07/19] Revert "Reapply "fix: ensure OAS 3.1 schemas with type array including "null" set nullable:true correctly and preserve properties"" This reverts commit 74eb333a3a551aff06c9353c0492616941f0c90d. --- .../codegen/OpenAPINormalizer.java | 18 +++-------- .../codegen/OpenAPINormalizerTest.java | 31 +------------------ .../src/test/resources/3_1/issue_24139.yaml | 6 ---- 3 files changed, 6 insertions(+), 49 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index f79dc954e119..64009e830628 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,19 +980,11 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - // OAS 3.1: if the type array includes "null", extract it and set nullable:true - // on the parent schema before normalizing its child properties. - // We intentionally do NOT call the full processNormalize31Spec here because - // that method can replace a JsonSchema with properties (but no explicit type) - // with an empty schema, discarding all properties. - if (getRule(NORMALIZE_31SPEC) && schema.getTypes() != null && schema.getTypes().contains("null")) { - schema.setNullable(true); - schema.getTypes().remove("null"); - if (schema.getTypes().size() == 1) { - schema.setType(String.valueOf(schema.getTypes().iterator().next())); - } - } - normalizeProperties(schema, visitedSchemas); + // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema + // before processing its properties, so that nullable:true is set correctly. + Schema result = processNormalize31Spec(schema, visitedSchemas); + normalizeProperties(result, visitedSchemas); + return result; } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index a512e736e29e..e23364828b52 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1921,36 +1921,7 @@ public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); assertEquals(nestedNullableAfter.getType(), "object"); - assertNotNull(nestedNullableAfter.getProperties(), - "NestedNullable properties must be preserved after normalization"); - } - - /** - * Regression test: an OAS 3.1 schema with properties but NO explicit type declaration - * must keep its properties after NORMALIZE_31SPEC normalization. - * Regression for a potential regression introduced by the fix for issue 24139. - */ - @Test - public void testIssue24139ImpliedObjectSchemaKeepsProperties() { - OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); - - Schema impliedBefore = openAPI.getComponents().getSchemas().get("ImpliedObject"); - assertNotNull(impliedBefore); - assertNotNull(impliedBefore.getProperties()); - - Map options = new HashMap<>(); - options.put("NORMALIZE_31SPEC", "true"); - OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); - openAPINormalizer.normalize(); - - Schema impliedAfter = openAPI.getComponents().getSchemas().get("ImpliedObject"); - assertNotNull(impliedAfter); - assertNotNull(impliedAfter.getProperties(), - "ImpliedObject (no explicit type, just properties) must keep its properties after normalization"); - assertNotNull(impliedAfter.getProperties().get("name"), - "ImpliedObject.name property must be preserved after normalization"); - assertNull(impliedAfter.getNullable(), - "ImpliedObject must not be marked nullable (no null type was declared)"); + assertNotNull(nestedNullableAfter.getProperties()); } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml index 69910a01bb06..57b172a507c2 100644 --- a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -15,12 +15,6 @@ components: properties: value: type: [ number, "null" ] - # OAS 3.1 allows object schemas with properties but no explicit type declaration. - # This must not lose its properties after normalization. - ImpliedObject: - properties: - name: - type: string Item: type: object From 500d93a500f910679b227063aeaab133f3ed0598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sat, 27 Jun 2026 15:20:14 +0200 Subject: [PATCH 08/19] Reapply "fix: ensure OAS 3.1 schemas with type array including "null" set nullable:true correctly and preserve properties" This reverts commit b0d188d9c44f8e653e15acf9b5bced72f0b7fa38. --- .../codegen/OpenAPINormalizer.java | 18 ++++++++--- .../codegen/OpenAPINormalizerTest.java | 31 ++++++++++++++++++- .../src/test/resources/3_1/issue_24139.yaml | 6 ++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index 64009e830628..f79dc954e119 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,11 +980,19 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema - // before processing its properties, so that nullable:true is set correctly. - Schema result = processNormalize31Spec(schema, visitedSchemas); - normalizeProperties(result, visitedSchemas); - return result; + // OAS 3.1: if the type array includes "null", extract it and set nullable:true + // on the parent schema before normalizing its child properties. + // We intentionally do NOT call the full processNormalize31Spec here because + // that method can replace a JsonSchema with properties (but no explicit type) + // with an empty schema, discarding all properties. + if (getRule(NORMALIZE_31SPEC) && schema.getTypes() != null && schema.getTypes().contains("null")) { + schema.setNullable(true); + schema.getTypes().remove("null"); + if (schema.getTypes().size() == 1) { + schema.setType(String.valueOf(schema.getTypes().iterator().next())); + } + } + normalizeProperties(schema, visitedSchemas); } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index e23364828b52..a512e736e29e 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1921,7 +1921,36 @@ public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); assertEquals(nestedNullableAfter.getType(), "object"); - assertNotNull(nestedNullableAfter.getProperties()); + assertNotNull(nestedNullableAfter.getProperties(), + "NestedNullable properties must be preserved after normalization"); + } + + /** + * Regression test: an OAS 3.1 schema with properties but NO explicit type declaration + * must keep its properties after NORMALIZE_31SPEC normalization. + * Regression for a potential regression introduced by the fix for issue 24139. + */ + @Test + public void testIssue24139ImpliedObjectSchemaKeepsProperties() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); + + Schema impliedBefore = openAPI.getComponents().getSchemas().get("ImpliedObject"); + assertNotNull(impliedBefore); + assertNotNull(impliedBefore.getProperties()); + + Map options = new HashMap<>(); + options.put("NORMALIZE_31SPEC", "true"); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); + openAPINormalizer.normalize(); + + Schema impliedAfter = openAPI.getComponents().getSchemas().get("ImpliedObject"); + assertNotNull(impliedAfter); + assertNotNull(impliedAfter.getProperties(), + "ImpliedObject (no explicit type, just properties) must keep its properties after normalization"); + assertNotNull(impliedAfter.getProperties().get("name"), + "ImpliedObject.name property must be preserved after normalization"); + assertNull(impliedAfter.getNullable(), + "ImpliedObject must not be marked nullable (no null type was declared)"); } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml index 57b172a507c2..69910a01bb06 100644 --- a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -15,6 +15,12 @@ components: properties: value: type: [ number, "null" ] + # OAS 3.1 allows object schemas with properties but no explicit type declaration. + # This must not lose its properties after normalization. + ImpliedObject: + properties: + name: + type: string Item: type: object From cf56cf5c3107cbaa969b535b49faa4e3d890b53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sat, 27 Jun 2026 15:20:20 +0200 Subject: [PATCH 09/19] Revert "fix: ensure OAS 3.1 schemas with type array including "null" set nullable:true correctly and preserve properties" This reverts commit cb5aa4917299ccce88cb1867e8e646f0bf2651ae. --- .../codegen/OpenAPINormalizer.java | 18 +++-------- .../codegen/OpenAPINormalizerTest.java | 31 +------------------ .../src/test/resources/3_1/issue_24139.yaml | 6 ---- 3 files changed, 6 insertions(+), 49 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index f79dc954e119..64009e830628 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,19 +980,11 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - // OAS 3.1: if the type array includes "null", extract it and set nullable:true - // on the parent schema before normalizing its child properties. - // We intentionally do NOT call the full processNormalize31Spec here because - // that method can replace a JsonSchema with properties (but no explicit type) - // with an empty schema, discarding all properties. - if (getRule(NORMALIZE_31SPEC) && schema.getTypes() != null && schema.getTypes().contains("null")) { - schema.setNullable(true); - schema.getTypes().remove("null"); - if (schema.getTypes().size() == 1) { - schema.setType(String.valueOf(schema.getTypes().iterator().next())); - } - } - normalizeProperties(schema, visitedSchemas); + // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema + // before processing its properties, so that nullable:true is set correctly. + Schema result = processNormalize31Spec(schema, visitedSchemas); + normalizeProperties(result, visitedSchemas); + return result; } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index a512e736e29e..e23364828b52 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1921,36 +1921,7 @@ public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); assertEquals(nestedNullableAfter.getType(), "object"); - assertNotNull(nestedNullableAfter.getProperties(), - "NestedNullable properties must be preserved after normalization"); - } - - /** - * Regression test: an OAS 3.1 schema with properties but NO explicit type declaration - * must keep its properties after NORMALIZE_31SPEC normalization. - * Regression for a potential regression introduced by the fix for issue 24139. - */ - @Test - public void testIssue24139ImpliedObjectSchemaKeepsProperties() { - OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); - - Schema impliedBefore = openAPI.getComponents().getSchemas().get("ImpliedObject"); - assertNotNull(impliedBefore); - assertNotNull(impliedBefore.getProperties()); - - Map options = new HashMap<>(); - options.put("NORMALIZE_31SPEC", "true"); - OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); - openAPINormalizer.normalize(); - - Schema impliedAfter = openAPI.getComponents().getSchemas().get("ImpliedObject"); - assertNotNull(impliedAfter); - assertNotNull(impliedAfter.getProperties(), - "ImpliedObject (no explicit type, just properties) must keep its properties after normalization"); - assertNotNull(impliedAfter.getProperties().get("name"), - "ImpliedObject.name property must be preserved after normalization"); - assertNull(impliedAfter.getNullable(), - "ImpliedObject must not be marked nullable (no null type was declared)"); + assertNotNull(nestedNullableAfter.getProperties()); } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml index 69910a01bb06..57b172a507c2 100644 --- a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -15,12 +15,6 @@ components: properties: value: type: [ number, "null" ] - # OAS 3.1 allows object schemas with properties but no explicit type declaration. - # This must not lose its properties after normalization. - ImpliedObject: - properties: - name: - type: string Item: type: object From f741e48e29a2fc8634d038ebcb9e7760cf405d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sat, 27 Jun 2026 15:20:29 +0200 Subject: [PATCH 10/19] Revert "fix: normalize OAS 3.1 schemas with type:[object,"null"] to set nullable:true correctly" This reverts commit 29c620709dc60c932b382d022f4506925e17a8c8. --- .../codegen/OpenAPINormalizer.java | 6 +--- .../codegen/OpenAPINormalizerTest.java | 29 ----------------- .../spring/KotlinSpringServerCodegenTest.java | 31 ------------------- .../src/test/resources/3_1/issue_24139.yaml | 31 ------------------- 4 files changed, 1 insertion(+), 96 deletions(-) delete mode 100644 modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index 64009e830628..f2909042bbba 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,11 +980,7 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema - // before processing its properties, so that nullable:true is set correctly. - Schema result = processNormalize31Spec(schema, visitedSchemas); - normalizeProperties(result, visitedSchemas); - return result; + normalizeProperties(schema, visitedSchemas); } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index e23364828b52..53cacea15650 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1896,33 +1896,4 @@ public void testLooseNullDefinitions() { ModelUtils.looseNullDefinitions = false; } - /** - * Verify that a schema defined as type:[object,"null"] WITH properties (OAS 3.1 style) - * is correctly normalized so that nullable:true is set on the schema itself. - * Regression test for https://github.com/OpenAPITools/openapi-generator/issues/24139 - */ - @Test - public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { - OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); - - // Before normalization: NestedNullable has types=[object,null], nullable is not yet set - Schema nestedNullableBefore = openAPI.getComponents().getSchemas().get("NestedNullable"); - assertNotNull(nestedNullableBefore); - assertNotNull(nestedNullableBefore.getProperties()); - - Map options = new HashMap<>(); - options.put("NORMALIZE_31SPEC", "true"); - OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); - openAPINormalizer.normalize(); - - // After normalization: nullable must be true and type must be "object" - Schema nestedNullableAfter = openAPI.getComponents().getSchemas().get("NestedNullable"); - assertNotNull(nestedNullableAfter); - assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, - "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); - assertEquals(nestedNullableAfter.getType(), "object"); - assertNotNull(nestedNullableAfter.getProperties()); - } - } - diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java index f7f06fd68429..7fbc5ceea289 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java @@ -6813,35 +6813,4 @@ public void paramJsonPropertyAnnotationWithDigitStartingPropertyName() throws IO "@param:JsonProperty(\"2nd_field\")\n @get:JsonProperty(\"2nd_field\") val `2ndField`" ); } - - /** - * Regression test for https://github.com/OpenAPITools/openapi-generator/issues/24139 - * A property that $ref's an OAS 3.1 schema with type:[object,"null"] is nullable and must - * NOT receive @field:JsonSetter(nulls = Nulls.FAIL). - */ - @Test(description = "issue 24139: nullable $ref (type:[object,null]) must not get @JsonSetter(nulls = Nulls.FAIL)") - public void testIssue24139NullableRefNoJsonSetterNullsFail() throws IOException { - Map additionalProperties = new HashMap<>(); - additionalProperties.put("useBeanValidation", true); - additionalProperties.put("openApiNullable", "true"); - - Map files = generateFromContract( - "src/test/resources/3_1/issue_24139.yaml", - additionalProperties - ); - - File itemFile = files.get("Item.kt"); - assertThat(itemFile).isNotNull(); - - // nestedNullable: $ref to NestedNullable (type:[object,"null"]) — nullable, no @JsonSetter(nulls = Nulls.FAIL) - assertFileNotContains(itemFile.toPath(), "nestedNullable: NestedNullable"); - // The field must NOT have @JsonSetter(nulls = Nulls.FAIL) because the referenced schema is nullable - String content = org.apache.commons.io.FileUtils.readFileToString(itemFile, StandardCharsets.UTF_8); - // Extract the nestedNullable field block and verify annotation absence - Assert.assertFalse( - content.contains("@field:JsonSetter(nulls = Nulls.FAIL)\n @param:JsonProperty(\"nestedNullable\")") || - content.contains("@field:JsonSetter(nulls = Nulls.FAIL)\n @get:JsonProperty(\"nestedNullable\")"), - "nestedNullable ($ref to nullable schema) must not have @JsonSetter(nulls = Nulls.FAIL)" - ); - } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml deleted file mode 100644 index 57b172a507c2..000000000000 --- a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml +++ /dev/null @@ -1,31 +0,0 @@ -openapi: 3.1.1 -info: - title: Test issue 24139 - version: 1.0.0 - -components: - schemas: - NestedNullable: - type: [ object, "null" ] - properties: - value: - type: [ number, "null" ] - Nested: - type: object - properties: - value: - type: [ number, "null" ] - - Item: - type: object - properties: - nestedNullable: - $ref: '#/components/schemas/NestedNullable' - - nestedNullable2: - anyOf: - - $ref: '#/components/schemas/Nested' - - type: 'null' - - nested: - $ref: '#/components/schemas/Nested' From 39ae5a2ed4a11835f6a4f66f515920e376633f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sat, 27 Jun 2026 15:53:24 +0200 Subject: [PATCH 11/19] Reapply "fix: normalize OAS 3.1 schemas with type:[object,"null"] to set nullable:true correctly" This reverts commit f741e48e29a2fc8634d038ebcb9e7760cf405d93. --- .../codegen/OpenAPINormalizer.java | 6 +++- .../codegen/OpenAPINormalizerTest.java | 29 +++++++++++++++++ .../spring/KotlinSpringServerCodegenTest.java | 31 +++++++++++++++++++ .../src/test/resources/3_1/issue_24139.yaml | 31 +++++++++++++++++++ 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index f2909042bbba..64009e830628 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,7 +980,11 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - normalizeProperties(schema, visitedSchemas); + // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema + // before processing its properties, so that nullable:true is set correctly. + Schema result = processNormalize31Spec(schema, visitedSchemas); + normalizeProperties(result, visitedSchemas); + return result; } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index 53cacea15650..e23364828b52 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1896,4 +1896,33 @@ public void testLooseNullDefinitions() { ModelUtils.looseNullDefinitions = false; } + /** + * Verify that a schema defined as type:[object,"null"] WITH properties (OAS 3.1 style) + * is correctly normalized so that nullable:true is set on the schema itself. + * Regression test for https://github.com/OpenAPITools/openapi-generator/issues/24139 + */ + @Test + public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); + + // Before normalization: NestedNullable has types=[object,null], nullable is not yet set + Schema nestedNullableBefore = openAPI.getComponents().getSchemas().get("NestedNullable"); + assertNotNull(nestedNullableBefore); + assertNotNull(nestedNullableBefore.getProperties()); + + Map options = new HashMap<>(); + options.put("NORMALIZE_31SPEC", "true"); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); + openAPINormalizer.normalize(); + + // After normalization: nullable must be true and type must be "object" + Schema nestedNullableAfter = openAPI.getComponents().getSchemas().get("NestedNullable"); + assertNotNull(nestedNullableAfter); + assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, + "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); + assertEquals(nestedNullableAfter.getType(), "object"); + assertNotNull(nestedNullableAfter.getProperties()); + } + } + diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java index 7fbc5ceea289..f7f06fd68429 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java @@ -6813,4 +6813,35 @@ public void paramJsonPropertyAnnotationWithDigitStartingPropertyName() throws IO "@param:JsonProperty(\"2nd_field\")\n @get:JsonProperty(\"2nd_field\") val `2ndField`" ); } + + /** + * Regression test for https://github.com/OpenAPITools/openapi-generator/issues/24139 + * A property that $ref's an OAS 3.1 schema with type:[object,"null"] is nullable and must + * NOT receive @field:JsonSetter(nulls = Nulls.FAIL). + */ + @Test(description = "issue 24139: nullable $ref (type:[object,null]) must not get @JsonSetter(nulls = Nulls.FAIL)") + public void testIssue24139NullableRefNoJsonSetterNullsFail() throws IOException { + Map additionalProperties = new HashMap<>(); + additionalProperties.put("useBeanValidation", true); + additionalProperties.put("openApiNullable", "true"); + + Map files = generateFromContract( + "src/test/resources/3_1/issue_24139.yaml", + additionalProperties + ); + + File itemFile = files.get("Item.kt"); + assertThat(itemFile).isNotNull(); + + // nestedNullable: $ref to NestedNullable (type:[object,"null"]) — nullable, no @JsonSetter(nulls = Nulls.FAIL) + assertFileNotContains(itemFile.toPath(), "nestedNullable: NestedNullable"); + // The field must NOT have @JsonSetter(nulls = Nulls.FAIL) because the referenced schema is nullable + String content = org.apache.commons.io.FileUtils.readFileToString(itemFile, StandardCharsets.UTF_8); + // Extract the nestedNullable field block and verify annotation absence + Assert.assertFalse( + content.contains("@field:JsonSetter(nulls = Nulls.FAIL)\n @param:JsonProperty(\"nestedNullable\")") || + content.contains("@field:JsonSetter(nulls = Nulls.FAIL)\n @get:JsonProperty(\"nestedNullable\")"), + "nestedNullable ($ref to nullable schema) must not have @JsonSetter(nulls = Nulls.FAIL)" + ); + } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml new file mode 100644 index 000000000000..57b172a507c2 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -0,0 +1,31 @@ +openapi: 3.1.1 +info: + title: Test issue 24139 + version: 1.0.0 + +components: + schemas: + NestedNullable: + type: [ object, "null" ] + properties: + value: + type: [ number, "null" ] + Nested: + type: object + properties: + value: + type: [ number, "null" ] + + Item: + type: object + properties: + nestedNullable: + $ref: '#/components/schemas/NestedNullable' + + nestedNullable2: + anyOf: + - $ref: '#/components/schemas/Nested' + - type: 'null' + + nested: + $ref: '#/components/schemas/Nested' From fbd542dfa7348796e317aa55f00480361ea5af4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sat, 27 Jun 2026 15:53:28 +0200 Subject: [PATCH 12/19] Reapply "fix: ensure OAS 3.1 schemas with type array including "null" set nullable:true correctly and preserve properties" This reverts commit cf56cf5c3107cbaa969b535b49faa4e3d890b53d. --- .../codegen/OpenAPINormalizer.java | 18 ++++++++--- .../codegen/OpenAPINormalizerTest.java | 31 ++++++++++++++++++- .../src/test/resources/3_1/issue_24139.yaml | 6 ++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index 64009e830628..f79dc954e119 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,11 +980,19 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema - // before processing its properties, so that nullable:true is set correctly. - Schema result = processNormalize31Spec(schema, visitedSchemas); - normalizeProperties(result, visitedSchemas); - return result; + // OAS 3.1: if the type array includes "null", extract it and set nullable:true + // on the parent schema before normalizing its child properties. + // We intentionally do NOT call the full processNormalize31Spec here because + // that method can replace a JsonSchema with properties (but no explicit type) + // with an empty schema, discarding all properties. + if (getRule(NORMALIZE_31SPEC) && schema.getTypes() != null && schema.getTypes().contains("null")) { + schema.setNullable(true); + schema.getTypes().remove("null"); + if (schema.getTypes().size() == 1) { + schema.setType(String.valueOf(schema.getTypes().iterator().next())); + } + } + normalizeProperties(schema, visitedSchemas); } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index e23364828b52..a512e736e29e 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1921,7 +1921,36 @@ public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); assertEquals(nestedNullableAfter.getType(), "object"); - assertNotNull(nestedNullableAfter.getProperties()); + assertNotNull(nestedNullableAfter.getProperties(), + "NestedNullable properties must be preserved after normalization"); + } + + /** + * Regression test: an OAS 3.1 schema with properties but NO explicit type declaration + * must keep its properties after NORMALIZE_31SPEC normalization. + * Regression for a potential regression introduced by the fix for issue 24139. + */ + @Test + public void testIssue24139ImpliedObjectSchemaKeepsProperties() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); + + Schema impliedBefore = openAPI.getComponents().getSchemas().get("ImpliedObject"); + assertNotNull(impliedBefore); + assertNotNull(impliedBefore.getProperties()); + + Map options = new HashMap<>(); + options.put("NORMALIZE_31SPEC", "true"); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); + openAPINormalizer.normalize(); + + Schema impliedAfter = openAPI.getComponents().getSchemas().get("ImpliedObject"); + assertNotNull(impliedAfter); + assertNotNull(impliedAfter.getProperties(), + "ImpliedObject (no explicit type, just properties) must keep its properties after normalization"); + assertNotNull(impliedAfter.getProperties().get("name"), + "ImpliedObject.name property must be preserved after normalization"); + assertNull(impliedAfter.getNullable(), + "ImpliedObject must not be marked nullable (no null type was declared)"); } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml index 57b172a507c2..69910a01bb06 100644 --- a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -15,6 +15,12 @@ components: properties: value: type: [ number, "null" ] + # OAS 3.1 allows object schemas with properties but no explicit type declaration. + # This must not lose its properties after normalization. + ImpliedObject: + properties: + name: + type: string Item: type: object From 080e3e2c124bb06fe7f191b512200f30becb0226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sat, 27 Jun 2026 15:53:32 +0200 Subject: [PATCH 13/19] Revert "Reapply "fix: ensure OAS 3.1 schemas with type array including "null" set nullable:true correctly and preserve properties"" This reverts commit 500d93a500f910679b227063aeaab133f3ed0598. --- .../codegen/OpenAPINormalizer.java | 18 +++-------- .../codegen/OpenAPINormalizerTest.java | 31 +------------------ .../src/test/resources/3_1/issue_24139.yaml | 6 ---- 3 files changed, 6 insertions(+), 49 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index f79dc954e119..64009e830628 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,19 +980,11 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - // OAS 3.1: if the type array includes "null", extract it and set nullable:true - // on the parent schema before normalizing its child properties. - // We intentionally do NOT call the full processNormalize31Spec here because - // that method can replace a JsonSchema with properties (but no explicit type) - // with an empty schema, discarding all properties. - if (getRule(NORMALIZE_31SPEC) && schema.getTypes() != null && schema.getTypes().contains("null")) { - schema.setNullable(true); - schema.getTypes().remove("null"); - if (schema.getTypes().size() == 1) { - schema.setType(String.valueOf(schema.getTypes().iterator().next())); - } - } - normalizeProperties(schema, visitedSchemas); + // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema + // before processing its properties, so that nullable:true is set correctly. + Schema result = processNormalize31Spec(schema, visitedSchemas); + normalizeProperties(result, visitedSchemas); + return result; } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index a512e736e29e..e23364828b52 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1921,36 +1921,7 @@ public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); assertEquals(nestedNullableAfter.getType(), "object"); - assertNotNull(nestedNullableAfter.getProperties(), - "NestedNullable properties must be preserved after normalization"); - } - - /** - * Regression test: an OAS 3.1 schema with properties but NO explicit type declaration - * must keep its properties after NORMALIZE_31SPEC normalization. - * Regression for a potential regression introduced by the fix for issue 24139. - */ - @Test - public void testIssue24139ImpliedObjectSchemaKeepsProperties() { - OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); - - Schema impliedBefore = openAPI.getComponents().getSchemas().get("ImpliedObject"); - assertNotNull(impliedBefore); - assertNotNull(impliedBefore.getProperties()); - - Map options = new HashMap<>(); - options.put("NORMALIZE_31SPEC", "true"); - OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); - openAPINormalizer.normalize(); - - Schema impliedAfter = openAPI.getComponents().getSchemas().get("ImpliedObject"); - assertNotNull(impliedAfter); - assertNotNull(impliedAfter.getProperties(), - "ImpliedObject (no explicit type, just properties) must keep its properties after normalization"); - assertNotNull(impliedAfter.getProperties().get("name"), - "ImpliedObject.name property must be preserved after normalization"); - assertNull(impliedAfter.getNullable(), - "ImpliedObject must not be marked nullable (no null type was declared)"); + assertNotNull(nestedNullableAfter.getProperties()); } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml index 69910a01bb06..57b172a507c2 100644 --- a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -15,12 +15,6 @@ components: properties: value: type: [ number, "null" ] - # OAS 3.1 allows object schemas with properties but no explicit type declaration. - # This must not lose its properties after normalization. - ImpliedObject: - properties: - name: - type: string Item: type: object From de3e753b3289ed3495f9997af697cfc7bdd31ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sat, 27 Jun 2026 15:53:37 +0200 Subject: [PATCH 14/19] Reapply "Reapply "fix: ensure OAS 3.1 schemas with type array including "null" set nullable:true correctly and preserve properties"" This reverts commit 7f0b9a6006ba58ba73b4e9aa33c6d0991ff8ea30. --- .../codegen/OpenAPINormalizer.java | 18 ++++++++--- .../codegen/OpenAPINormalizerTest.java | 31 ++++++++++++++++++- .../src/test/resources/3_1/issue_24139.yaml | 6 ++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index 64009e830628..f79dc954e119 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -980,11 +980,19 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { return schema; } else if (ModelUtils.hasProperties(schema)) { - // Normalize OAS 3.1 type arrays (e.g. type:[object,"null"]) on the parent schema - // before processing its properties, so that nullable:true is set correctly. - Schema result = processNormalize31Spec(schema, visitedSchemas); - normalizeProperties(result, visitedSchemas); - return result; + // OAS 3.1: if the type array includes "null", extract it and set nullable:true + // on the parent schema before normalizing its child properties. + // We intentionally do NOT call the full processNormalize31Spec here because + // that method can replace a JsonSchema with properties (but no explicit type) + // with an empty schema, discarding all properties. + if (getRule(NORMALIZE_31SPEC) && schema.getTypes() != null && schema.getTypes().contains("null")) { + schema.setNullable(true); + schema.getTypes().remove("null"); + if (schema.getTypes().size() == 1) { + schema.setType(String.valueOf(schema.getTypes().iterator().next())); + } + } + normalizeProperties(schema, visitedSchemas); } else if (schema.getAdditionalProperties() instanceof Schema) { // map normalizeMapSchema(schema); normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index e23364828b52..a512e736e29e 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1921,7 +1921,36 @@ public void testIssue24139NullableObjectWithPropertiesGetsNullableTrue() { assertEquals(nestedNullableAfter.getNullable(), Boolean.TRUE, "NestedNullable with type:[object,\"null\"] should have nullable:true after normalization"); assertEquals(nestedNullableAfter.getType(), "object"); - assertNotNull(nestedNullableAfter.getProperties()); + assertNotNull(nestedNullableAfter.getProperties(), + "NestedNullable properties must be preserved after normalization"); + } + + /** + * Regression test: an OAS 3.1 schema with properties but NO explicit type declaration + * must keep its properties after NORMALIZE_31SPEC normalization. + * Regression for a potential regression introduced by the fix for issue 24139. + */ + @Test + public void testIssue24139ImpliedObjectSchemaKeepsProperties() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_24139.yaml"); + + Schema impliedBefore = openAPI.getComponents().getSchemas().get("ImpliedObject"); + assertNotNull(impliedBefore); + assertNotNull(impliedBefore.getProperties()); + + Map options = new HashMap<>(); + options.put("NORMALIZE_31SPEC", "true"); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); + openAPINormalizer.normalize(); + + Schema impliedAfter = openAPI.getComponents().getSchemas().get("ImpliedObject"); + assertNotNull(impliedAfter); + assertNotNull(impliedAfter.getProperties(), + "ImpliedObject (no explicit type, just properties) must keep its properties after normalization"); + assertNotNull(impliedAfter.getProperties().get("name"), + "ImpliedObject.name property must be preserved after normalization"); + assertNull(impliedAfter.getNullable(), + "ImpliedObject must not be marked nullable (no null type was declared)"); } } diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml index 57b172a507c2..69910a01bb06 100644 --- a/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml +++ b/modules/openapi-generator/src/test/resources/3_1/issue_24139.yaml @@ -15,6 +15,12 @@ components: properties: value: type: [ number, "null" ] + # OAS 3.1 allows object schemas with properties but no explicit type declaration. + # This must not lose its properties after normalization. + ImpliedObject: + properties: + name: + type: string Item: type: object From a275fa019c99f3630a4e2267e7af332cbb491d78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sat, 27 Jun 2026 15:53:40 +0200 Subject: [PATCH 15/19] Reapply "add whitespace to retrigger tests" This reverts commit 68e6dfffafcd0578de9cd370f00fd9a4dd2d222d. --- .../codegen/kotlin/spring/KotlinSpringServerCodegenTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java index f7f06fd68429..fb53bafa3ad0 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java @@ -6814,6 +6814,7 @@ public void paramJsonPropertyAnnotationWithDigitStartingPropertyName() throws IO ); } + /** * Regression test for https://github.com/OpenAPITools/openapi-generator/issues/24139 * A property that $ref's an OAS 3.1 schema with type:[object,"null"] is nullable and must From 7eca93517dd35fe24c2de390b8cfd56d967395fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sun, 28 Jun 2026 11:11:41 +0200 Subject: [PATCH 16/19] ci: replace setup-cpp with apt-get in node2 to fix transient GPG key failures setup-cpp internally adds ppa:ubuntu-toolchain-r/test, which fetches an external GPG key. This occasionally times out in CI, causing the node2 job to fail with 'Failed to install the llvm' even though the code is fine. Replace the wget/setup-cpp/source chain with a single apt-get install of clang, cmake, and ninja-build from Ubuntu's own repositories. No PPAs, no external GPG key fetches, no transient network failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CI/circle_parallel.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CI/circle_parallel.sh b/CI/circle_parallel.sh index 83d48b12aeb1..b9049faa6d36 100755 --- a/CI/circle_parallel.sh +++ b/CI/circle_parallel.sh @@ -21,12 +21,8 @@ if [ "$NODE_INDEX" = "1" ]; then elif [ "$NODE_INDEX" = "2" ]; then echo "Running node $NODE_INDEX to test cpp-restsdk" - # install cpprestsdk - sudo apt-get install libcpprest-dev - wget "https://github.com/aminya/setup-cpp/releases/download/v0.37.0/setup-cpp-x64-linux" - chmod +x ./setup-cpp-x64-linux - sudo ./setup-cpp-x64-linux --compiler llvm --cmake true --ninja true - source ~/.cpprc # activate cpp environment variables + # install cpprestsdk and C++ build tools via apt (avoids setup-cpp's PPA/GPG key fetch) + sudo apt-get install -y libcpprest-dev clang cmake ninja-build (cd samples/client/petstore/cpp-restsdk/client && mvn integration-test) From c327dfc24e66c888f460a5b0b808a0856f4c0e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sun, 28 Jun 2026 11:23:40 +0200 Subject: [PATCH 17/19] fix: add explicit source directory '.' to cmake invocation in cpp-restsdk pom.xml CMake warns 'No source or binary directory provided' when called without a positional source-dir argument or -S/-B flags. The warning notes this will become a fatal error in future CMake releases. Add '.' as the first cmake argument to explicitly set the source directory to the current directory, which matches the implicit behaviour and silences the warning. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- samples/client/petstore/cpp-restsdk/client/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/client/petstore/cpp-restsdk/client/pom.xml b/samples/client/petstore/cpp-restsdk/client/pom.xml index 6c5f5ed24c96..b8a0aff520c7 100644 --- a/samples/client/petstore/cpp-restsdk/client/pom.xml +++ b/samples/client/petstore/cpp-restsdk/client/pom.xml @@ -35,6 +35,7 @@ cmake + . -DCMAKE_CXX_FLAGS="-I/usr/local/opt/openssl/include" -DCMAKE_MODULE_LINKER_FLAGS="-L/usr/local/opt/openssl/lib" -DCMAKE_BUILD_TYPE=Debug From c2169e62e8e020b91c48d026f5a11bcf7771264d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sun, 28 Jun 2026 11:29:01 +0200 Subject: [PATCH 18/19] fix: force clang compiler in cpp-restsdk cmake invocation The CI node2 job installs clang via apt, but cmake was defaulting to GCC because no compiler was explicitly specified. Add CMAKE_C_COMPILER=clang and CMAKE_CXX_COMPILER=clang++ to match the original intent of the setup, which previously used setup-cpp --compiler llvm. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- samples/client/petstore/cpp-restsdk/client/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/client/petstore/cpp-restsdk/client/pom.xml b/samples/client/petstore/cpp-restsdk/client/pom.xml index b8a0aff520c7..5287c089dc84 100644 --- a/samples/client/petstore/cpp-restsdk/client/pom.xml +++ b/samples/client/petstore/cpp-restsdk/client/pom.xml @@ -36,6 +36,8 @@ cmake . + -DCMAKE_C_COMPILER=clang + -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS="-I/usr/local/opt/openssl/include" -DCMAKE_MODULE_LINKER_FLAGS="-L/usr/local/opt/openssl/lib" -DCMAKE_BUILD_TYPE=Debug From b7807bd0cf4c0f4e10a1771f2d4eb5c98e77a050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Metli=C4=8Dka?= Date: Sun, 28 Jun 2026 12:00:56 +0200 Subject: [PATCH 19/19] ci: remove unnecessary ninja-build from node2 apt install The cpp-restsdk pom.xml uses cmake + make (Unix Makefiles generator). Ninja is never invoked, so ninja-build serves no purpose here. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CI/circle_parallel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/circle_parallel.sh b/CI/circle_parallel.sh index b9049faa6d36..b004e6e8b80c 100755 --- a/CI/circle_parallel.sh +++ b/CI/circle_parallel.sh @@ -22,7 +22,7 @@ elif [ "$NODE_INDEX" = "2" ]; then echo "Running node $NODE_INDEX to test cpp-restsdk" # install cpprestsdk and C++ build tools via apt (avoids setup-cpp's PPA/GPG key fetch) - sudo apt-get install -y libcpprest-dev clang cmake ninja-build + sudo apt-get install -y libcpprest-dev clang cmake (cd samples/client/petstore/cpp-restsdk/client && mvn integration-test)