Skip to content

[Repo Assist] fix: resolve oneOf/anyOf with single $ref to referenced type#375

Merged
sergey-tihon merged 2 commits intomasterfrom
repo-assist/fix-issue-243-oneof-anyof-single-ref-43295ab7101879ec
Apr 13, 2026
Merged

[Repo Assist] fix: resolve oneOf/anyOf with single $ref to referenced type#375
sergey-tihon merged 2 commits intomasterfrom
repo-assist/fix-issue-243-oneof-anyof-single-ref-43295ab7101879ec

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

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

Closes #243

Root Cause

The v3 DefinitionCompiler already handles allOf: [$ref] with a single entry — it resolves the reference and returns the correct type. However, oneOf: [$ref] and anyOf: [$ref] with a single entry were not handled, so they fell through to compileNewObject()obj.

These patterns are semantically equivalent to a direct $ref and are common in:

  • Schemas generated by NSwag, Kiota, AutoRest
  • OpenAPI 3.1 schemas using anyOf: [$ref] as the nullable type annotation (alongside nullable: true)

Fix

Add handlers for oneOf/anyOf with a single $ref entry immediately after the existing allOf single-ref handler, following the same pattern:

// Handle oneOf with single reference (resolves to the referenced type)
| _ when
    not(isNull schemaObj.OneOf)
    && schemaObj.OneOf.Count = 1
    && (schemaObj.Properties |> isNull || schemaObj.Properties.Count = 0)
    ->
    match schemaObj.OneOf.[0] with
    | :? OpenApiSchemaReference as schemaRef when not(isNull schemaRef.Reference) ->
        ns.ReleaseNameReservation tyName
        compileByPath <| getFullPath schemaRef.Reference.Id
    | _ -> compileNewObject()

Also extend the resolvedType inference guard to check oneOf/anyOf single-entry types when schemaObj.Type is absent.

Changes

File Change
src/SwaggerProvider.DesignTime/v3/DefinitionCompiler.fs Add oneOf/anyOf single-ref handlers and type inference
tests/SwaggerProvider.Tests/v3/Schema.TypeMappingTests.fs Add 6 tests: oneOf/anyOf with string and int aliases, required and optional

Test Status

✅ Build: succeeded (0 errors, pre-existing warnings only)
✅ Unit tests: 328 passed, 0 failed, 2 skipped (all pass, 6 new tests added)
✅ Format check: fantomas --check passed on changed files

Integration/provider tests require a running Swashbuckle test server. The changed code is in the compile-time schema resolution path; it does not affect HTTP, serialization, or runtime behaviour.

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

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@7ee2b60744abf71b985bead4599640f165edcd93

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

When a schema uses `oneOf: [$ref]` or `anyOf: [$ref]` with a single entry,
resolve to the referenced type instead of falling through to `obj`.

This pattern is common in OpenAPI specs generated by tools (e.g. NSwag,
Kiota, AutoRest) and in OpenAPI 3.1 schemas that use oneOf/anyOf for
nullable type annotations.

Previously only `allOf: [$ref]` (the OpenAPI 3.0 canonical form) was
handled; the equivalent oneOf and anyOf forms produced `obj` instead of
the referenced type.

Changes:
- DefinitionCompiler.fs: add oneOf/anyOf single-ref handlers after the
  existing allOf single-ref handler; also extend the type-inference guard
  to check oneOf/anyOf single-entry type when schemaObj.Type is missing
- Schema.TypeMappingTests.fs: add 6 tests covering oneOf and anyOf with
  primitive and object aliases, required and optional variants

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sergey-tihon sergey-tihon marked this pull request as ready for review April 13, 2026 04:40
Copilot AI review requested due to automatic review settings April 13, 2026 04:40
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

This PR fixes OpenAPI v3 schema compilation so that oneOf: [ $ref ] and anyOf: [ $ref ] (single-entry wrappers) resolve to the referenced schema type rather than incorrectly falling back to obj, matching the existing allOf: [ $ref ] handling in DefinitionCompiler.

Changes:

  • Extend v3 DefinitionCompiler to resolve oneOf/anyOf with a single $ref entry to the referenced type (mirroring the allOf single-ref behavior).
  • Improve type inference when schemaObj.Type is missing by looking into single-entry oneOf/anyOf subschemas.
  • Add v3 unit tests validating oneOf/anyOf single-ref alias resolution for required and optional properties.

Reviewed changes

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

File Description
src/SwaggerProvider.DesignTime/v3/DefinitionCompiler.fs Adds single-$ref handlers for oneOf/anyOf and expands missing-Type inference to cover those wrappers.
tests/SwaggerProvider.Tests/v3/Schema.TypeMappingTests.fs Adds tests ensuring oneOf/anyOf single-ref wrappers resolve to the referenced primitive alias type (including optional/value-type wrapping).

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

@sergey-tihon sergey-tihon merged commit 36e9409 into master Apr 13, 2026
6 checks passed
@sergey-tihon sergey-tihon deleted the repo-assist/fix-issue-243-oneof-anyof-single-ref-43295ab7101879ec branch April 13, 2026 04:51
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.

allOf / oneOf issue with multiple content types in response or requests objects

2 participants