OpenAPITools / OpenAPITools/openapi-generator

[BUG] [typescript-fetch] Model and property name collision with other model can cause weird codegen bugs

Open
#17,909 2 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
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)?
  • 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

There is a weird name collision issue when the model of a property is "similar" to the name of an actual model. More specifically, similar here means that camelize(object_property_field) == some_model_name. To make this more concrete, in the following example, the User model has a tier property, which internally is represented as User_tier (at least that's what I found when stepping with the debugger). It happens that camelize("User_tier") == "UserTier" which causes troubles when it's time to process the actual UserTier model (early returns in the code path, uses the cached model processing).

For this specific example, a weird side-effect is that the generated model code is incorrect, with cyclic imports and missing definitions:

/* tslint:disable */
/* eslint-disable */
/**
 * FastAPI
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: 0.1.0
 * 
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

import { exists, mapValues } from '../runtime';
import type { UserTier } from './UserTier';
import {
    UserTierFromJSON,
    UserTierFromJSONTyped,
    UserTierToJSON,
} from './UserTier';

/**
 * 
 * @export
 * @interface UserTier
 */
export interface UserTier {
}

/**
 * Check if a given object implements the UserTier interface.
 */
export function instanceOfUserTier(value: object): boolean {
    let isInstance = true;

    return isInstance;
}

export function UserTierFromJSON(json: any): UserTier {
    return UserTierFromJSONTyped(json, false);
}

export function UserTierFromJSONTyped(json: any, ignoreDiscriminator: boolean): UserTier {
    return json;
}

export function UserTierToJSON(value?: UserTier | null): any {
    return value;
}

Simply changing the property name fixes issue, since there is no longer a collision.

openapi-generator version

7.3.0

OpenAPI declaration file content or url
{
    "openapi": "3.1.0",
    "info": {
        "title": "FastAPI",
        "version": "0.1.0"
    },
    "components": {
        "schemas": {
            "UserTier": {
                "type": "string",
                "enum": [
                    "Tier1",
                    "Tier2"
                ],
                "title": "UserTier"
            },
            "User": {
                "properties": {
                    "tier": {
                        "anyOf": [
                            {
                                "$ref": "#/components/schemas/UserTier"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    }
                },
                "type": "object",
                "title": "User"
            }
        }
    }
}
Generation Details

I'm using the npm wrapper to invoke the generator:
npx openapi-generator-cli generate -g "typescript-fetch" -i openapi.json -o ./out --additional-properties packageName=test,projectName=test,useSingleRequestParameter=false

Steps to reproduce

Pass the weird collision schema to the generator.

Related issues/PRs
Suggest a fix

Some logic must be added to check if the camelized schema name of a model property is already taken by a "top level" model. For example here, camelize("User_tier") produces UserTier which is inserted in the model map, causing the subsequent processing of the actual UserTier model to follow an early-return path and skip further processing.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the reported npx openapi-generator-cli command with the supplied OpenAPI schema and the typescript-fetch generator. Trace how the User.tier property and UserTier schema are processed, then verify that generated User and UserTier code has no cyclic imports or missing definitions.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, typescript
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.