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
- Pick a different target name in --name-mapping, e.g. foo=schema_ or foo=schema_name instead of foo=schema
- Rename the source property in the OpenAPI spec so its generated name no longer collides
- Drop --compatible-with-python-legacy if you do not need 5.x-style model behavior; without it, non-mapped properties skip this strict check
- 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
- Review --name-mapping targets against pydantic BaseModel/model-class member names before adopting them
- Prefer renaming the property in the spec over ad-hoc mappings when possible
- Only enable --compatible-with-python-legacy when the legacy metadata members are actually required
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
- properties %s and %s in model %s both accept input name %s
- properties %s and %s in model %s both use Python member name
- property %s in model %s uses generated storage name %s, whic
- property %s in model %s cannot use %s as its public Python n
- property %s in model %s has invalid generated Python field n
AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22).
Data as JSON: /api/errors/08c43b11d08fca08.
Report an issue: GitHub.