Skip to content

oneOf variant listed twice in request-body example dropdown when its subtree contains an unrelated nested oneOf #1143

Description

@ahridin

RapiDoc version: 9.3.8 (also present as of the current latest, 9.3.8 — no newer release exists yet)

Bug: When a request body schema is a top-level oneOf (with discriminator.mapping), the EXAMPLE dropdown lists a variant twice instead of once, but only if that variant's schema subtree transitively contains an unrelated, independent nested oneOf somewhere deeper (e.g. a property that is itself oneOf: [string, SomeObject]). Variants with no nested oneOf in their subtree render correctly, once each.

Repro spec (OpenAPI 3.1):

{
  "openapi": "3.1.0",
  "info": { "title": "oneOf duplicate example repro", "version": "1.0.0" },
  "paths": {
    "/things": {
      "post": {
        "requestBody": {
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/Request" } }
          }
        },
        "responses": { "200": { "description": "ok" } }
      }
    }
  },
  "components": {
    "schemas": {
      "Request": {
        "oneOf": [
          { "$ref": "#/components/schemas/PlainVariant" },
          { "$ref": "#/components/schemas/NestedOneOfVariant" }
        ],
        "discriminator": {
          "propertyName": "kind",
          "mapping": {
            "plain": "#/components/schemas/PlainVariant",
            "nested": "#/components/schemas/NestedOneOfVariant"
          }
        }
      },
      "PlainVariant": {
        "type": "object",
        "properties": {
          "kind": { "type": "string", "enum": ["plain"] },
          "value": { "type": "string" }
        }
      },
      "NestedOneOfVariant": {
        "type": "object",
        "properties": {
          "kind": { "type": "string", "enum": ["nested"] },
          "entry": { "$ref": "#/components/schemas/EntryRef" }
        }
      },
      "EntryRef": {
        "oneOf": [
          { "type": "string" },
          { "$ref": "#/components/schemas/EntryObject" }
        ]
      },
      "EntryObject": {
        "type": "object",
        "properties": { "id": { "type": "string" } }
      }
    }
  }
}

Steps to reproduce:

  1. Load the spec above via <rapi-doc spec-url="..."> with rapidoc@9.3.8.
  2. Open the POST /things operation, go to the request body's EXAMPLE dropdown.
  3. Expected: 2 entries, PlainVariant and NestedOneOfVariant, each once.
  4. Actual: NestedOneOfVariant appears twice; PlainVariant (which has no nested oneOf) appears once. The trigger is specifically the nested, unrelated oneOf in EntryRef — it's unrelated to the top-level discriminator.

Isolation notes: We built up to this minimal case incrementally: a flat top-level oneOf with 2 variants (no duplication) → adding allOf-based composition to each variant (still no duplication) → adding a nested oneOf to only one variant's subtree (that variant, and only that variant, doubles in the dropdown). This isolates the nested oneOf as the trigger, independent of the discriminator/allOf mechanics.

Real-world impact: In our OpenAPI 3.1 spec, a top-level oneOf Request schema (10 discriminated variants) has every variant transitively referencing a schema that is itself oneOf: [string, SomeObject] via a sessions array property — so all 10 variants appear twice in the request-body EXAMPLE dropdown (20 entries, each name duplicated back-to-back).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions