Skip to content

fix(library): serialize additionalProperties schema in OpenAPI V2 documents#2744

Open
Copilot wants to merge 2 commits intomainfrom
copilot/fix-openapi-schema-issue
Open

fix(library): serialize additionalProperties schema in OpenAPI V2 documents#2744
Copilot wants to merge 2 commits intomainfrom
copilot/fix-openapi-schema-issue

Conversation

Copy link
Contributor

Copilot AI commented Feb 19, 2026

Since v2.3.11, additionalProperties with a schema value was silently dropped during OpenAPI v2 serialization, causing information loss for dictionary-type responses (e.g., IDictionary<string, MyModel>). The SerializeAsV2 method had an incorrect comment "a schema cannot be serialized in v2" — the OpenAPI v2.0 spec does support additionalProperties as either a boolean or a schema object.

Before (broken):

schema:
  type: object
  # additionalProperties missing — information lost

After (correct):

schema:
  type: object
  additionalProperties:
    $ref: '#/definitions/TestItemResult'

Description

Serialization rules for additionalProperties in V2 (consistent with V3):

  • AdditionalProperties schema set → serialize as schema object
  • AdditionalPropertiesAllowed = false → serialize false
  • AdditionalPropertiesAllowed = true (default) → omit (no-op)

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):

Related Issue(s)

Changes Made

  • OpenApiSchema.SerializeAsV2: removed incorrect guard that prevented AdditionalProperties schema from being written; added WriteOptionalObject call mirroring the V3 path
  • Renamed test SerializeAdditionalPropertiesAsV2DoesNotEmitSerializeAdditionalPropertiesAsV2WithEmptySchemaEmits with corrected expectation
  • Added SerializeAdditionalPropertiesAsV2WithRefSchemaEmits to cover the dictionary-with-$ref case from the issue

Testing

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

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.

See the contributing guidelines for more information about how patches are applied across multiple versions.

Additional Notes

Regression introduced in PR #2630 which was intended to suppress spurious additionalProperties: false in v3.1 but inadvertently also suppressed valid schema-valued additionalProperties in v2.

Original prompt

This section details on the original issue you should resolve

<issue_title>additionalProperties not set in schema for OpenApi V2 documents since v2.3.11, loss of information in things that return dictionaries</issue_title>
<issue_description>Describe the bug

We have some C# code with a schema that returns an IDictionary, where the value is a C# object, e.g.

public class TestItemResult
{
    public bool IsMatched { get; set; }
    public string? Reason { get; set; }
}


[HttpGet("test-items")]
public async Task<IDictionary<string, TestItemResult>> TestItem(...)
{
    // returns a dictionary of test item name to test result
}

Our OpenApi generation is configured to set.

OpenApiVersion = OpenApiSpecVersion.OpenApi2_0;

We are using OpenApi indirectly via Swashbuckle.AspNetCore, we picked up the change transitively with an upgrade from Swashbuckle.AspNetCore version 10.1.0 to 10.1.2, which changes the referenced version of Microsoft.OpenApi from 2.3.9 to 2.4.2

Expected behavior

With OpenApi 2.3.9, the response looks like this

  '/test-items':
    get:
      summary: ...
      produces:
        - application/json
      responses:
        '200':
          description: ...
          schema:
            type: object
            additionalProperties:
              $ref: '#/definitions/TestItemResult'

When browsing using swagger UI, the model is

{
  < * >:	TestItemResult{
    IsMatched: boolean
    Reason: string
  }
}

And the example response is

{
  "additionalProp1": {
    "IsMatched": true,
    "Reason": "string"
  },
  "additionalProp2": {
    "IsMatched": true,
    "Reason": "string"
  },
  "additionalProp3": {
    "IsMatched": true,
    "Reason": "string"
  }
}

From our perspective these are all correct and expected.

Actual behavior

Since OpenApi 2.3.11, the response looks like this (note additionalProperties missing)

  '/test-items':
    get:
      summary: ...
      produces:
        - application/json
      responses:
        '200':
          description: ...
          schema:
            type: object

When browsing using swagger UI, the model is

{
}

And the example response is

{}

Additional context

I looked at the OpenApi release history / changelog, and noted that the change starts with Issue 2619, wherein a user observes "Additional properties false" is incorrectly added to every object in shcema when switching to OpenAPI 3.1

It was then marked fixed in

  • PR 2630 - fix: additional properties serialization should not emit a schema in v2 fix: additional properties serialization should not emit booleans in v3.1+
  • PR 2631 - fix/additional properties to v3

Looking at the discussion in the issue and PR's, it looks as though the fix was intended to prevent spurious additionalProperties: false in v3.

It has also removed information from a v2 schema, which doesn't seem to fit with the intent of the bug fix.

If we pick up the new version, our customers will experience this as loss of information/functionality in the swagger document.

Was this loss of information intentional, and if so would it be possible to help us understand why, and/or if there are any changes we can make our our end to work around the issue?

Thank you

</issue_description>

<agent_instructions>follow instructions provided in copilot instructions and contributing.
Look at my reply for the fix that needs to be implemented.
Start by updating unit tests first, then fix the implementation.</agent_instructions>

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

@baywet Hi @borland, Thank you for using the SDK and for reaching out.

Yes, the additionalProperties keyword should be serialized the same way across all versions since it's present since OpenAPI v2.0 and defined as a schema or boolean since JSON schema draft 04:

  • When the boolean property is set to false, serialize false
  • When the schema property is set to a schema, serialize the schema
  • Otherwise, ignore the property

As for deserialization:

  • If the value is set to false, deserialize that for the boolean property.
  • If the value is an object, attempt deserializing a schema for the schema property.
  • Otherwise do nothing, the default value should be true for the boolean property.

Is this something you'd like to submit a pull request for provided some guidance?

Related #2727 #2716</comment_new>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix additionalProperties not set in OpenApi V2 schema fix(library): serialize additionalProperties schema in OpenAPI V2 documents Feb 19, 2026
Copilot AI requested a review from baywet February 19, 2026 20:51
@baywet baywet marked this pull request as ready for review February 19, 2026 23:01
@baywet baywet requested a review from a team as a code owner February 19, 2026 23:01
@baywet baywet requested a review from Copilot February 19, 2026 23:01
@baywet baywet enabled auto-merge February 19, 2026 23:01
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a regression introduced in v2.3.11 (PR #2630) where additionalProperties with a schema value was silently dropped during OpenAPI v2 serialization, causing information loss for dictionary-type responses (e.g., IDictionary<string, MyModel>). The fix removes an incorrect comment and guard that prevented schema-valued additionalProperties from being serialized, which contradicts the OpenAPI v2.0 specification that supports additionalProperties as either a boolean or a schema object.

Changes:

  • Removed incorrect guard preventing schema-valued additionalProperties serialization in V2
  • Updated test to reflect correct behavior for empty schema
  • Added test case for dictionary-with-$ref scenario

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/Microsoft.OpenApi/Models/OpenApiSchema.cs Fixed SerializeAsV2 method to properly serialize additionalProperties schema, matching V3+ behavior and V2 spec requirements
test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs Renamed test to reflect correct expectation and added new test for dictionary-with-$ref case

@sonarqubecloud
Copy link

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.

additionalProperties not set in schema for OpenApi V2 documents since v2.3.11, loss of information in things that return dictionaries

2 participants

Comments