Bug Report Checklist
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
- Save the spec above as
spec.yaml
- Run the command above
- 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.
Bug Report Checklist
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 mangleschema names before emitting types, so the inline schema
importMembers_requestand the spec-definedImportMembersRequestboth become the modelImportMembersRequest. The raw keys differ, no collision isdetected, and one model ends up replacing the other.
openapi-generator version
7.25.0-SNAPSHOT, built frommasterat commit4aed9c1c635.OpenAPI declaration file content or url
Generation Details
typescript-fetchis only used for a short reproduction — the collision happens inInlineModelResolver, so this is generator-agnostic (it reproduces the same way for Java, Spring, etc.).Steps to reproduce
spec.yamlout/models/Actual output
Only one model file is produced, and it has the inline schema's properties:
declaredFieldAanddeclaredFieldBare gone./members/echo, which explicitly$refsImportMembersRequest, 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:
Suggest a fix
https://github.com/OpenAPITools/openapi-generator/blob/4aed9c1c635/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java#L919-L932
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 + "_" + countfallback 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,InlineModelResolvercollisions, and inline schemasoverwriting components; I could not find an existing report of this specific mangling collision.