Skip to content

[BUG] [Engine?] InlineModelResolver merges different inline enums that have the same values #23978

@theresa-fun

Description

@theresa-fun

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

After upgrading from 7.22.0 to 7.23.0, inline enums that share the same values but are defined on different properties are no longer generated as separate types. Instead, only the first enum gets its own schema and the second one silently reuses it.

In my spec I have two properties on the same object that both use the same enum values but represent completely different things. In 7.22.0 each property got its own enum type. In 7.23.0 only the first one is generated and the second property just gets the type of the first one.

I bisected the issue and it is introduced by commit 170778a (PR #23856). I built a snapshot from the commit before and from the commit after and confirmed that this is where the behavior changes.

openapi-generator version

7.23.0 (works correctly in 7.22.0)

OpenAPI declaration file content or url

Minimal reproducer:

openapi: 3.0.2
info:
  title: Enum Dedup Bug Reproducer
  version: 1.0.0
paths:
  "/orders/{id}":
    get:
      operationId: getOrder
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"
          description: OK
components:
  schemas:
    Order:
      type: object
      required:
        - orderId
        - shirtSize
        - pantSize
      properties:
        orderId:
          type: integer
        shirtSize:
          description: "The size of the shirt ordered by the customer"
          type: string
          enum:
            - XS
            - S
            - M
            - L
            - XL
        pantSize:
          description: "The size of the pants ordered by the customer"
          type: string
          enum:
            - XS
            - S
            - M
            - L
            - XL
Generation Details
npx @openapitools/openapi-generator-cli generate \
  -i reproducer.yaml \
  -g scala-http4s \
  -o output/ \
  --global-property models

All generators that have RESOLVE_INLINE_ENUMS=true set by default are affected:

Generator Codegen file
scala-http4s ScalaHttp4sClientCodegen.java
rust-server RustServerCodegen.java
rust-server (deprecated) RustServerCodegenDeprecated.java
php-flight PhpFlightServerCodegen.java
php-laravel PhpLaravelServerCodegen.java

Any other generator where a user manually passes --inline-schema-options RESOLVE_INLINE_ENUMS=true is also affected.

Steps to reproduce
  1. Save the yaml above as reproducer.yaml
  2. Generate with 7.22.0. You get two enum files: OrderShirtSize and OrderPantSize
  3. Generate with 7.23.0. You only get OrderShirtSize. The pantSize field now uses OrderShirtSize as its type

I also tested with rust-server and php-flight and the same thing happens there.

Related issues/PRs

Introduced by commit 170778a (PR #23856).

Suggest a fix

It looks like the issue could be in the matchGenerated() method in InlineModelResolver.java. The structural fallback compares schemas without their description field, which could cause two different inline enums with the same values to look identical.

A possible approach could be to only allow the structural fallback to match when the proposed schema name shares the same base as the existing one. That way it could still handle the parser mutation case but would not merge unrelated enums.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions