OpenAPITools/openapi-generator · error · IllegalArgumentException

properties %s and %s in model %s both accept input name %s

Error message

properties %s and %s in model %s both accept input name %s

What it means

When a model uses explicit public names (--name-mapping), each property accepts input under its wire name (baseName) and/or its public alias. The generator tracks every accepted input name per model and throws this IllegalArgumentException when two different properties accept the same input name, because the generated __init__/alias logic could not decide which property a given input belongs to.

Source

Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java:856

            }
            if (explicitPublicName
                    && (!property.name.matches("[A-Za-z][A-Za-z0-9_]*")
                    || PYTHON_KEYWORDS.contains(property.name)
                    || MODEL_FIELD_NAME_COLLISIONS.contains(property.name)
                    || MODEL_CLASS_BODY_NAMES.contains(property.name)
                    || PYDANTIC_PRIVATE_MEMBER_NAMES.contains(property.name))) {
                throw new IllegalArgumentException(String.format(Locale.ROOT,
                        "property %s in model %s has invalid generated Python field name %s",
                        property.baseName, model.name, property.name));
            }

            for (String inputName : List.of(property.baseName, publicName)) {
                CodegenProperty owner = inputNameOwners.putIfAbsent(inputName, property);
                if (owner != null
                        && !owner.baseName.equals(property.baseName)
                        && (explicitPublicName || owner.vendorExtensions.containsKey(
                                CodegenConstants.X_PY_EXPLICIT_PUBLIC_NAME))) {
                    throw new IllegalArgumentException(String.format(Locale.ROOT,
                            "properties %s and %s in model %s both accept input name %s",
                            owner.baseName, property.baseName, model.name, inputName));
                }
            }
            for (String memberName : List.of(property.name, publicName)) {
                CodegenProperty owner = memberNameOwners.putIfAbsent(memberName, property);
                if (owner != null
                        && !owner.baseName.equals(property.baseName)
                        && (explicitPublicName || owner.vendorExtensions.containsKey(
                                CodegenConstants.X_PY_EXPLICIT_PUBLIC_NAME))) {
                    throw new IllegalArgumentException(String.format(Locale.ROOT,
                            "properties %s and %s in model %s both use Python member name %s",
                            owner.baseName, property.baseName, model.name, memberName));
                }
            }
        }
        for (CodegenProperty property : generatedProperties) {
            if (!property.vendorExtensions.containsKey(

View on GitHub (pinned to fcec517be3)

Solutions

  1. Make each --name-mapping target unique within the model and not equal to any sibling property's wire name
  2. If you intended to merge the two properties, fix the spec instead: one property, one wire name
  3. Rename the colliding property in the OpenAPI spec so the mapping target is free

Example fix

# before: model User has properties 'name' and 'full_name'; mapping aliases 'name' -> 'full_name'
openapi-generator-cli generate -i api.yaml -g python --name-mapping name=full_name
# after
openapi-generator-cli generate -i api.yaml -g python --name-mapping name=display_name
Defensive patterns

Strategy: validation

Validate before calling

# Ensure no two properties accept the same input name (Python):
def input_names(props):
    names = []
    for base, public in props:  # (wire name, mapped public name or None)
        names.append(base)
        if public:
            names.append(public)
    return names

seen = set()
for n in input_names(model_props):
    assert n not in seen, f'two properties accept input name {n}'
    seen.add(n)

Try / catch

try {
    new DefaultGenerator().opts(input).generate();
} catch (IllegalArgumentException e) {
    // message: 'properties A and B in model M both accept input name N'
    // remove the mapping that aliases A (or B) onto N and regenerate
}

Prevention

When it happens

Trigger: -g python --name-mapping a=b on a model that already has a property named b: property a now accepts input 'b' (its public alias) which is also property b's wire name.

Common situations: Mapping a new property onto an existing sibling's name; mappings authored per-service by different people that accidentally target an existing wire name; renames during API evolution where old and new names coexist in one model.

Related errors


AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22). Data as JSON: /api/errors/497b04b0a33a2e22. Report an issue: GitHub.