Description
When an inline enum's inferred model name collides with a named component schema, both models are written to the same payload file. One silently overwrites the other, and the aggregate http_client.ts / client file then imports a symbol that no longer exists.
Generation reports zero errors — the breakage only appears when the generated package is type-checked.
This is more serious than the compile error suggests: a generated model is silently lost. In a spec where the two colliding models happen to be structurally compatible, there would be no type error at all, and the consumer would get the wrong model at runtime.
Reproduction
Two schemas whose generated names collide:
components.schemas.PackageType — an object (code, description, …), returned by GET /package_types
components.schemas.LoadCarrier.properties.package_type — an inline enum (PALLET, PARCEL, …), whose name Modelina infers from the property as PackageType
{
"openapi": "3.0.1",
"info": { "title": "Collision repro", "version": "1.0.0" },
"paths": {
"/package_types": {
"get": {
"operationId": "packageTypesGet",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": { "$ref": "#/components/schemas/PackageType" }
}
}
}
}
}
}
},
"/load_carriers": {
"get": {
"operationId": "loadCarriersGet",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/LoadCarrier" }
}
}
}
}
}
}
},
"components": {
"schemas": {
"PackageType": {
"type": "object",
"properties": {
"code": { "type": "string" },
"description": { "type": "string" }
}
},
"LoadCarrier": {
"type": "object",
"properties": {
"package_type": {
"type": "string",
"enum": ["PALLET", "PARCEL", "BOX"]
}
}
}
}
}
}
Config: channels (protocol http_client) + client (protocol http), the standard OpenAPI client pair from examples/openapi-http-client.
codegen generate && tsc --noEmit
Actual output
payload/PackageType.ts contains only the enum — the object model is gone:
enum PackageType {
PALLET = 'PALLET',
PARCEL = 'PARCEL',
BOX = 'BOX'
}
export { PackageType };
Compare a non-colliding payload, which exports both:
export { PackagesItem };
export type { PackagesItemInterface };
http_client.ts then imports the same symbol twice — once for each model that thought it owned the file:
import { PackageType } from './payload/PackageType'; // line 123 — the enum
import { PackageType, PackageTypeInterface } from './payload/PackageType'; // line 246 — the object
TS2300: Duplicate identifier 'PackageType'.
TS2305: Module './payload/PackageType' has no exported member 'PackageTypeInterface'.
Six errors across http_client.ts and the generated client class — both entry-point files, so nothing downstream compiles.
Expected
Colliding names should be disambiguated so both models survive, and the aggregate imports should reference the disambiguated names.
The disambiguation logic already works elsewhere in the same run: an inline enum at PackagesItem.properties.package_type correctly became PackagesItemPackageType in its own file. The same spec produced a bare PackageType for LoadCarrier.properties.package_type, so the prefixing is applied inconsistently — that inconsistency is probably the root cause and the cheapest place to look.
Worth deciding as part of the fix: whether a name collision should be a hard generation error rather than a warning, since the silent-overwrite case is undetectable downstream.
Notes
The import dedup in generateHttpClient (src/codegen/generators/typescript/client/protocols/http.ts:172) uses [...new Set(dependencies)] on whole import strings, so two differently-shaped imports of the same symbol both survive. Deduping by symbol rather than by string would turn this into a single wrong-import error instead of a duplicate-identifier one — but that's a symptom, not the cause. The collision itself is the bug.
Environment
- CLI version: 0.82.1 (built from source, matches published
latest)
- Node: 22
- OS: Windows 11
- Input: OpenAPI 3.0.1, 72 paths / 88 operations
Description
When an inline enum's inferred model name collides with a named component schema, both models are written to the same payload file. One silently overwrites the other, and the aggregate
http_client.ts/ client file then imports a symbol that no longer exists.Generation reports zero errors — the breakage only appears when the generated package is type-checked.
This is more serious than the compile error suggests: a generated model is silently lost. In a spec where the two colliding models happen to be structurally compatible, there would be no type error at all, and the consumer would get the wrong model at runtime.
Reproduction
Two schemas whose generated names collide:
components.schemas.PackageType— an object (code,description, …), returned byGET /package_typescomponents.schemas.LoadCarrier.properties.package_type— an inline enum (PALLET,PARCEL, …), whose name Modelina infers from the property asPackageType{ "openapi": "3.0.1", "info": { "title": "Collision repro", "version": "1.0.0" }, "paths": { "/package_types": { "get": { "operationId": "packageTypesGet", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PackageType" } } } } } } } }, "/load_carriers": { "get": { "operationId": "loadCarriersGet", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoadCarrier" } } } } } } } }, "components": { "schemas": { "PackageType": { "type": "object", "properties": { "code": { "type": "string" }, "description": { "type": "string" } } }, "LoadCarrier": { "type": "object", "properties": { "package_type": { "type": "string", "enum": ["PALLET", "PARCEL", "BOX"] } } } } } }Config:
channels(protocolhttp_client) +client(protocolhttp), the standard OpenAPI client pair fromexamples/openapi-http-client.codegen generate && tsc --noEmitActual output
payload/PackageType.tscontains only the enum — the object model is gone:Compare a non-colliding payload, which exports both:
http_client.tsthen imports the same symbol twice — once for each model that thought it owned the file:Six errors across
http_client.tsand the generated client class — both entry-point files, so nothing downstream compiles.Expected
Colliding names should be disambiguated so both models survive, and the aggregate imports should reference the disambiguated names.
The disambiguation logic already works elsewhere in the same run: an inline enum at
PackagesItem.properties.package_typecorrectly becamePackagesItemPackageTypein its own file. The same spec produced a barePackageTypeforLoadCarrier.properties.package_type, so the prefixing is applied inconsistently — that inconsistency is probably the root cause and the cheapest place to look.Worth deciding as part of the fix: whether a name collision should be a hard generation error rather than a warning, since the silent-overwrite case is undetectable downstream.
Notes
The import dedup in
generateHttpClient(src/codegen/generators/typescript/client/protocols/http.ts:172) uses[...new Set(dependencies)]on whole import strings, so two differently-shaped imports of the same symbol both survive. Deduping by symbol rather than by string would turn this into a single wrong-import error instead of a duplicate-identifier one — but that's a symptom, not the cause. The collision itself is the bug.Environment
latest)