Skip to content

fix(library): do not emit unevaluatedProperties for non-object schemas#2774

Merged
baywet merged 3 commits intomainfrom
copilot/fix-unevaluated-properties-serialization
Mar 13, 2026
Merged

fix(library): do not emit unevaluatedProperties for non-object schemas#2774
baywet merged 3 commits intomainfrom
copilot/fix-unevaluated-properties-serialization

Conversation

Copy link
Contributor

Copilot AI commented Mar 13, 2026

unevaluatedProperties: false was being serialized on schemas whose type is array, string, number, integer, boolean, or null — types for which this keyword has no semantic effect in JSON Schema 2020-12.

Changes Made

  • WriteJsonSchemaKeywords (v3.1+ native property): skip unevaluatedProperties when Type is set and does not include the Object flag
  • SerializeInternal (v2.0/v3.0 x-jsonschema-unevaluatedProperties extension): same guard
  • SerializeAsV2 private method: same guard

Guard condition: !Type.HasValue || (Type.Value & JsonSchemaType.Object) != 0

Preserves emission when Type is unset (required for anyOf/oneOf/allOf composition patterns) and when type includes object.

Before:

"EmployeeList": {
  "unevaluatedProperties": false,
  "type": "array",
  "items": { "$ref": "#/components/schemas/EmployeeResponse" }
}

After:

"EmployeeList": {
  "type": "array",
  "items": { "$ref": "#/components/schemas/EmployeeResponse" }
}

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Other (please describe):

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • All existing tests pass

New tests cover:

  • Each non-object type (array, string, number, integer, boolean, null) not emitting unevaluatedProperties: false in v3.1
  • Same for UnevaluatedPropertiesSchema in v3.1
  • Non-object types not emitting the extension in v2.0/v3.0
  • Regression: object type still emits unevaluatedProperties
  • Regression: unset Type still emits unevaluatedProperties

Checklist

  • My code follows the code style of this project
  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Versions applicability

  • My change applies to the version 1.X of the library, if so PR link:
  • My change applies to the version 2.X of the library, if so PR link:
  • My change applies to the version 3.X of the library, if so PR link:
  • I have evaluated the applicability of my change against the other versions above.

Additional Notes

This fix intentionally does not handle mixed types (e.g., ["object", "array"]) or complex composition scenarios as out of scope for this PR.

Original prompt

This section details on the original issue you should resolve

<issue_title>OpenAPI.NET 3.4 emits unevaluatedProperties for non-object schemas</issue_title>
<issue_description>## Describe the bug

In OpenAPI.NET 3.4, unevaluatedProperties: false is emitted on schemas
whose type is not object, for example arrays and primitive types.

Example:

"EmployeeList": {
  "unevaluatedProperties": false,
  "type": "array",
  "items": {
    "$ref": "#/components/schemas/EmployeeResponse"
  },
  "description": "List of employees."
}

unevaluatedProperties is only meaningful for object schemas. When
emitted on an array, string, number, integer, boolean, or null schema,
it has no effect and appears to be serializer noise.

Expected behavior

unevaluatedProperties should only be serialized when the schema is an
object schema, or otherwise when it can actually apply to object
validation.

Example (valid usage):

{
  "type": "object",
  "properties": {
    "name": { "type": "string" }
  },
  "unevaluatedProperties": false
}

Example (should not include it):

{
  "type": "array",
  "items": {
    "$ref": "#/components/schemas/EmployeeResponse"
  }
}

Actual behavior

unevaluatedProperties: false is emitted for schemas whose type is:

  • array
  • string
  • number
  • integer
  • boolean

While harmless for validation, this creates unnecessary noise in
generated OpenAPI documents and can confuse downstream consumers.

Why this matters

OpenAPI 3.1 adopts JSON Schema 2020‑12 semantics. In JSON Schema,
unevaluatedProperties applies to object validation, while array
control is handled by unevaluatedItems.

Because of this, emitting unevaluatedProperties on non-object schemas
appears unnecessary and misleading.

Steps to reproduce

Generate an OpenAPI 3.1 document using OpenAPI.NET 3.4 with component
schemas that include arrays or primitive types.

Example generated output:

"Date": {
  "unevaluatedProperties": false,
  "type": "string",
  "format": "date"
}
"EmployeeList": {
  "unevaluatedProperties": false,
  "type": "array",
  "items": {
    "$ref": "#/components/schemas/EmployeeResponse"
  }
}

Proposed fix

Only emit unevaluatedProperties when:

  • the schema type is object
  • or the schema participates in object validation where the keyword is
    meaningful

Do not emit it for:

  • type: array
  • type: string
  • type: number
  • type: integer
  • type: boolean
  • type: null

Version info

  • OpenAPI.NET: 3.4.0
  • OpenAPI document version: 3.1.x
    </issue_description>

<agent_instructions>start by adding/updating unit tests first.
the solution is to not emit the unevaluatedProperties property if the type is set to array, string, boolean, integer, null, number.
the solution is NOT to check whether the type is set to "object" this is because there are more complex cases with any/one/all of where the type might not be set on the root schema. I do not want you to handle the most complex scenarios as part of this pull request.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

When `Type` is explicitly set and does not include `Object`, skip
emitting `unevaluatedProperties` in all serialization paths (v3.1+
native property, v2.0/v3.0 extension, and direct v2.0 serialization).

Closes: unevaluatedProperties emitted for array/string/number/integer/boolean/null schemas

Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix unevaluatedProperties emission for non-object schemas fix(library): do not emit unevaluatedProperties for non-object schemas Mar 13, 2026
Copilot AI requested a review from baywet March 13, 2026 13:17
@baywet baywet marked this pull request as ready for review March 13, 2026 13:41
@baywet baywet requested a review from a team as a code owner March 13, 2026 13:41
@baywet baywet enabled auto-merge March 13, 2026 13:42
@sonarqubecloud
Copy link

@baywet baywet merged commit 852fb4c into main Mar 13, 2026
18 checks passed
@baywet baywet deleted the copilot/fix-unevaluated-properties-serialization branch March 13, 2026 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenAPI.NET 3.4 emits unevaluatedProperties for non-object schemas

3 participants