OpenAPITools/openapi-generator · error · IllegalArgumentException

property %s in model %s uses generated Python member name %s

Error message

property %s in model %s uses generated Python member name %s

What it means

When the python generator runs with --compatible-with-python-legacy or with a --name-mapping entry, it validates every property's public name and storage name against the set of members the generated model class itself defines (model class body names, model metadata, pydantic private members, legacy metadata names). If a mapped public name or the storage name equals one of those reserved generated members, generation aborts with this IllegalArgumentException.

Source

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

                    CodegenConstants.X_PY_PUBLIC_NAME, property.name);
            boolean explicitPublicName = property.vendorExtensions.containsKey(
                    CodegenConstants.X_PY_EXPLICIT_PUBLIC_NAME);
            boolean legacyMetadataCollision = compatibleWithPythonLegacy
                    && (LEGACY_MODEL_METADATA_MEMBER_NAMES.contains(publicName)
                    || LEGACY_MODEL_METADATA_MEMBER_NAMES.contains(property.name));
            boolean publicNameCollision = generatedMembers.contains(publicName)
                    && (explicitPublicName
                    || legacyMetadataCollision
                    || nameMappingGeneratedMembers.contains(publicName));
            boolean storageNameCollision = generatedMembers.contains(property.name)
                    && (explicitPublicName
                    || legacyMetadataCollision
                    || nameMappingGeneratedMembers.contains(property.name));
            if (publicNameCollision || storageNameCollision) {
                String generatedMemberName = publicNameCollision
                        ? publicName
                        : property.name;
                throw new IllegalArgumentException(String.format(Locale.ROOT,
                        "property %s in model %s uses generated Python member name %s",
                        property.baseName, model.name, generatedMemberName));
            }
            if (explicitPublicName
                    && (!publicName.matches("[A-Za-z_][A-Za-z0-9_]*")
                    || PYTHON_KEYWORDS.contains(publicName)
                    || publicName.startsWith("__"))) {
                throw new IllegalArgumentException(String.format(Locale.ROOT,
                        "property %s in model %s cannot use %s as its public Python name",
                        property.baseName, model.name, publicName));
            }
            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,

View on GitHub (pinned to fcec517be3)

Solutions

  1. Pick a different target name in --name-mapping, e.g. foo=schema_ or foo=schema_name instead of foo=schema
  2. Rename the source property in the OpenAPI spec so its generated name no longer collides
  3. Drop --compatible-with-python-legacy if you do not need 5.x-style model behavior; without it, non-mapped properties skip this strict check
  4. List the reserved members (MODEL_CLASS_BODY_NAMES, MODEL_FIELD_NAME_COLLISIONS, pydantic private names) from PythonClientCodegen and treat them as blocked names in your mapping review

Example fix

# before
openapi-generator-cli generate -i api.yaml -g python --name-mapping json_payload=json
# after
openapi-generator-cli generate -i api.yaml -g python --name-mapping json_payload=json_payload
Defensive patterns

Strategy: validation

Validate before calling

# Reject mappings onto names the generated model class owns (Python):
BLOCKED = {'schema', 'json', 'copy', 'dict', 'validate', 'construct', 'fields',
           'model_fields', 'model_dump', 'from_orm', 'parse_obj'}  # extend from PythonClientCodegen lists
for target in mapping_targets:
    assert target not in BLOCKED, f'{target} collides with a generated model member'

Try / catch

try {
    new DefaultGenerator().opts(input).generate();
} catch (IllegalArgumentException e) {
    // message: 'property X in model Y uses generated Python member name Z'
    // fix the --name-mapping entry for X (or rename the property), then regenerate
}

Prevention

When it happens

Trigger: -g python --name-mapping foo=schema (public name collides with pydantic BaseModel.schema), or --name-mapping foo=json / foo=copy / foo=fields, or any property whose generated storage name hits a class-body name while --compatible-with-python-legacy is on.

Common situations: Teams adopting --name-mapping to rename snake_case wire properties to friendlier Python names accidentally map onto BaseModel/model-class members (schema, json, copy, validate, fields, dict). Legacy-mode users hit it when a spec property naturally sanitizes to one of the legacy metadata member names.

Related errors


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