Skip to content

[Repo Assist] fix: preserve declared properties when schema has both properties and additionalProperties#383

Merged
sergey-tihon merged 2 commits intomasterfrom
repo-assist/fix-additionalprops-with-properties-20260415-ce61b01ef5996249
Apr 16, 2026
Merged

[Repo Assist] fix: preserve declared properties when schema has both properties and additionalProperties#383
sergey-tihon merged 2 commits intomasterfrom
repo-assist/fix-additionalprops-with-properties-20260415-ce61b01ef5996249

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

🤖 This PR was created by Repo Assist, an automated AI assistant.

Summary

Fixes a bug where an OpenAPI schema object defining both properties and additionalProperties was compiled as a plain Map<string, T>, silently discarding all the explicitly declared named properties.

Root Cause

In DefinitionCompiler.fs, the guard for the dictionary path was:

| _ when
    resolvedType = Some JsonSchemaType.Object
    && not(isNull schemaObj.AdditionalProperties)
    -> // Dictionary

This condition fired whenever additionalProperties was present, regardless of whether the schema also had explicit properties. As a result, a schema like:

MyObj:
  type: object
  properties:
    name:
      type: string
  additionalProperties:
    type: integer

would produce Map<string, int> and the Name property would be inaccessible.

Fix

Added && (schemaObj.Properties |> isNull || schemaObj.Properties.Count = 0) to the guard, so the Map path is only taken when no explicit properties are declared. When both are present, the type falls through to compileNewObject(), which correctly produces a provided type with all declared properties.

This matches the pattern already used for the allOf/oneOf/anyOf single-reference cases (which also guard on Properties.Count = 0).

Trade-offs

The additionalProperties typing is not surfaced for the mixed case (same as before, and a known limitation of the current architecture). The named properties are now accessible via the generated type, which is the more useful outcome.

Test Status

  • ✅ All 281 existing unit tests pass (SwaggerProvider.Tests)
  • ✅ New regression test added: object with properties and additionalProperties compiles to object type not Map
  • Format checked with dotnet fantomas --check

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@97143ac59cb3a13ef2a77581f929f06719c7402a

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@97143ac59cb3a13ef2a77581f929f06719c7402a

…alProperties

When a schema object defines both `properties` and `additionalProperties`,
the compiler previously treated the type as a plain dictionary (Map<string, T>)
and silently discarded all the explicitly declared properties.

The fix adds a guard so that the Map path only fires when the schema object has
NO explicitly declared properties. When both are present the type falls through
to compileNewObject(), which produces a proper provided type with all declared
properties. This is a better approximation than losing the named properties
entirely; the additionalProperties typing is not captured (as before), which is
an acceptable trade-off given the current architecture.

A regression test is added to Schema.ArrayAndMapTypeMappingTests.fs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sergey-tihon sergey-tihon marked this pull request as ready for review April 16, 2026 07:34
Copilot AI review requested due to automatic review settings April 16, 2026 07:34
Copy link
Copy Markdown
Contributor

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

Fixes an OpenAPI schema compilation bug where type: object schemas that define both properties and additionalProperties were incorrectly compiled as Map<string, T>, dropping explicitly declared properties.

Changes:

  • Tightened the “dictionary/Map” guard in DefinitionCompiler.fs to only apply when no explicit properties are declared.
  • Added a regression test ensuring mixed properties + additionalProperties schemas compile to an object type and preserve declared properties.

Reviewed changes

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

File Description
src/SwaggerProvider.DesignTime/DefinitionCompiler.fs Prevents the dictionary compilation path when properties are present, preserving named fields.
tests/SwaggerProvider.Tests/Schema.ArrayAndMapTypeMappingTests.fs Adds regression coverage for the mixed object schema case to avoid future regressions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sergey-tihon sergey-tihon merged commit ef45da3 into master Apr 16, 2026
6 checks passed
@sergey-tihon sergey-tihon deleted the repo-assist/fix-additionalprops-with-properties-20260415-ce61b01ef5996249 branch April 16, 2026 07:42
github-actions Bot added a commit that referenced this pull request Apr 18, 2026
Capture the 9 PRs merged since beta01 (April 14 – April 18):
- fix: preserve properties+additionalProperties (#383)
- refactor: CallAsync returns HttpResponseMessage (#385)
- eng: remove stale YamlDotNet dependency (#386)
- test: +18 OperationCompiler tests (#380, #386)
- docs: README and VitePress site updates (#379, #382)
- ci: Dependabot action bumps (#387-#390)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sergey-tihon pushed a commit that referenced this pull request Apr 19, 2026
* docs: add 4.0.0-beta02 release notes entry

Capture the 9 PRs merged since beta01 (April 14 – April 18):
- fix: preserve properties+additionalProperties (#383)
- refactor: CallAsync returns HttpResponseMessage (#385)
- eng: remove stale YamlDotNet dependency (#386)
- test: +18 OperationCompiler tests (#380, #386)
- docs: README and VitePress site updates (#379, #382)
- ci: Dependabot action bumps (#387-#390)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: trigger checks

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants