Skip to content

[BUG] Inline request-body schema silently overwrites a spec-defined schema with a mangled-equal name #24548

Description

@donald

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

An inline request-body schema can silently overwrite a schema declared in components.schemas,
deleting its properties from the generated code. There is no error and no warning — the generated
client simply has the wrong contract for an endpoint that never used an inline schema in the first place.

InlineModelResolver.uniqueName() compares candidate names by raw string only. But generators mangle
schema names before emitting types, so the inline schema importMembers_request and the spec-defined
ImportMembersRequest both become the model ImportMembersRequest. The raw keys differ, no collision is
detected, and one model ends up replacing the other.

openapi-generator version

7.25.0-SNAPSHOT, built from master at commit 4aed9c1c635.

OpenAPI declaration file content or url
openapi: 3.0.3
info: { title: t, version: 1.0.0 }
paths:
  /members/import:
    post:
      operationId: importMembers          # inline body -> "importMembers_request"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                inlineOnly: { type: string }
      responses: { "200": { description: ok } }
  /members/echo:
    post:
      operationId: echoMembers
      requestBody:
        content:
          application/json:
            schema: { $ref: "#/components/schemas/ImportMembersRequest" }
      responses: { "200": { description: ok } }
components:
  schemas:
    ImportMembersRequest:                 # mangles to the same model name
      properties:
        declaredFieldA: { type: string }
        declaredFieldB: { type: integer }
Generation Details
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \
  -i spec.yaml -g typescript-fetch -o out

typescript-fetch is only used for a short reproduction — the collision happens in
InlineModelResolver, so this is generator-agnostic (it reproduces the same way for Java, Spring, etc.).

Steps to reproduce
  1. Save the spec above as spec.yaml
  2. Run the command above
  3. Look at out/models/

Actual output

Only one model file is produced, and it has the inline schema's properties:

out/models/
├── ImportMembersRequest.ts
└── index.ts
// ImportMembersRequest.ts
export interface ImportMembersRequest {
    inlineOnly?: string;      // <- the inline body schema won
}

declaredFieldA and declaredFieldB are gone. /members/echo, which explicitly $refs
ImportMembersRequest, now serialises the wrong shape. Exit code is 0; nothing is logged.

Expected output

Two distinct models — the spec-defined one untouched, and the inline one under a non-colliding name:

// ImportMembersRequest.ts
export interface ImportMembersRequest {
    declaredFieldA?: string;
    declaredFieldB?: number;
}
// ImportMembersRequest1.ts
export interface ImportMembersRequest1 {
    inlineOnly?: string;
}
Suggest a fix

https://github.com/OpenAPITools/openapi-generator/blob/4aed9c1c635/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java#L919-L932

if (!openAPI.getComponents().getSchemas().containsKey(uniqueName) && !uniqueNames.contains(uniqueName)) {
    return uniqueName;
}

The check is exact-string. Making it normalization-aware (ignore separators and case, i.e. compare the
way the name will look after mangling) turns this into a detected collision, and the existing
name + "_" + count fallback then keeps both models.

I have a patch with a regression test ready and will open a PR shortly.

Related issues/PRs

Searched open and closed issues/PRs for uniqueName, InlineModelResolver collisions, and inline schemas
overwriting components; I could not find an existing report of this specific mangling collision.

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