OpenAPITools / OpenAPITools/openapi-generator
[BUG][typescript-axios] Missing import for a $ref under additionalProperties on a 3.1 nullable property
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- What's the version of OpenAPI Generator used?
- Have you search for related issues/PRs?
- What's the actual output vs expected output?
- [Optional] Bounty to sponsor the fix
Description
When a property is nullable using an OpenAPI 3.1 type array ("type": ["null", "object"]) and its additionalProperties is a $ref, the generated model references the $ref'd type but never imports it, so the output does not compile.
Instead of importing the referenced model, the generator emits an import for a Null model that it never writes:
// @ts-ignore
import type { Null } from './null'; // <- ./null is never generated
export interface ParentNullableMap {
'map'?: { [key: string]: Child; }; // <- Child referenced, never imported
}
tsc then fails with:
models/parent-nullable-map.ts(21,30): error TS2304: Cannot find name 'Child'.
Two things narrow it down:
- The nullable type array is what triggers it. With
"type": "object"instead of"type": ["null", "object"], the same property importsChildcorrectly. additionalPropertiesis specific. A nullable array of the same$ref("type": ["null", "array"]withitems: {$ref}) is generated correctly, in the same run — included below as a control.
The nullable is also silently dropped on the affected property: 'map'?: { [key: string]: Child; } has no | null, while the control correctly produces 'list'?: Array<Child> | null.
Reproduces with withSeparateModelsAndApi=true.
openapi-generator version
7.24.0 (via the openapitools/openapi-generator-cli:v7.24.0 Docker image). Not tested against earlier versions.
OpenAPI declaration file content or url
{
"openapi": "3.1.0",
"info": {"title": "repro", "version": "1.0.0"},
"paths": {},
"components": {
"schemas": {
"Child": {"type": "object", "properties": {"name": {"type": "string"}}},
"ParentNullableMap": {
"type": "object",
"properties": {
"map": {"type": ["null", "object"], "additionalProperties": {"$ref": "#/components/schemas/Child"}}
}
},
"ParentNullableArray": {
"type": "object",
"properties": {
"list": {"type": ["null", "array"], "items": {"$ref": "#/components/schemas/Child"}}
}
}
}
}
}
validate reports no errors on this spec (only "unused model" recommendations, since paths is empty).
Command line used for generation
docker run --rm -v "$PWD:/local" openapitools/openapi-generator-cli:v7.24.0 \
generate -i /local/minimal.json -g typescript-axios -o /local/out \
--additional-properties=withSeparateModelsAndApi=true,modelPackage=models,apiPackage=api
Steps to reproduce
- Save the spec above as
minimal.json. - Run the command above.
models/parent-nullable-map.tsimportsNullfrom./nulland referencesChildwith no import for it.models/null.tsdoes not exist.models/parent-nullable-array.ts— the control — importsChildcorrectly.- Type-check the output, e.g.
tsc --noEmit --strict --skipLibCheck --target es2020 --module esnext --moduleResolution bundler models/*.ts, and it fails withTS2304: Cannot find name 'Child'.
Actual output
// models/parent-nullable-map.ts (BROKEN)
// @ts-ignore
import type { Null } from './null';
export interface ParentNullableMap {
'map'?: { [key: string]: Child; };
}
// models/parent-nullable-array.ts (control, correct)
// @ts-ignore
import type { Child } from './child';
export interface ParentNullableArray {
'list'?: Array<Child> | null;
}
Expected output
// models/parent-nullable-map.ts
import type { Child } from './child';
export interface ParentNullableMap {
'map'?: { [key: string]: Child; } | null;
}
Related issues/PRs
- #5601 — same missing-import symptom in
typescript-axioswithwithSeparateModelsAndApi, but a different trigger:additionalPropertiesof type array with a$ref, on OpenAPI 3.0. That report notes the plainadditionalProperties: {$ref}case works, which matches what I see — it only breaks here once the 3.1 nullable type array is added. - #9385 — missing import for a nested dictionary-of-collection type; possibly the same import-resolution path.
Suggest a fix
The nullable type array appears to be consumed before the $ref inside additionalProperties is registered as an import, and a Null model is substituted in its place. Two observations that may help locate it:
- The
Nullimport is emitted for the nullable-type-array case generally, not only when a bare{"type": "null"}schema exists — the spec above contains no such schema, yet the import appears. - The
// @ts-ignoreabove generated imports masks the dangling./nullimport, so the failure surfaces at the usage site rather than the import, which makes it harder to trace. In the array (control) path the same@ts-ignoreline is present but the import is correct.
A workaround for anyone hitting this: pre-process the spec to drop "null" from the type array on properties whose additionalProperties is a $ref (accepting the loss of nullability on those properties), which restores a compiling client.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with minimal.json and run the listed openapi-generator Docker command for typescript-axios. Compare models/parent-nullable-map.ts with models/parent-nullable-array.ts and type-check with the supplied tsc command; done means Child is imported, nullability is preserved, no nonexistent Null model is referenced, and the generated models compile.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, openapi, typescript
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 64/100