Skip to content

[core] Resolve primitive aliases for the oneOf discriminator property type - #25227

Open
cmuchinsky wants to merge 1 commit into
OpenAPITools:masterfrom
cmuchinsky:fix/oneof-discriminator-primitive-alias
Open

cmuchinsky wants to merge 1 commit into
OpenAPITools:masterfrom
cmuchinsky:fix/oneof-discriminator-primitive-alias

Conversation

@cmuchinsky

@cmuchinsky cmuchinsky commented Oct 12, 2026 •

Copy link
Copy Markdown

fix #25226

When the discriminator property of all the subtypes mapped by a oneOf is a $ref to the same alias of a primitive type (e.g. ShapeKind: {type: string}), DefaultCodegen#getCommonSchemaType (added by #24812) returns the name of the alias schema as the type of the getter of the generated oneOf interface. No model is generated for such an alias, so the generated code does not compile, while the subtypes use String:

public interface Shape {
    public ShapeKind getKind();   // error: cannot find symbol, class ShapeKind (7.25.0: public String getKind();)
}

The schema is now unaliased first, like getSingleSchemaType does for the property type of the subtypes. A $ref that is still present afterwards (enum, object, composed schema, schemaMappings target) is still used as a model name, so the behavior added by #24812 for enums is unchanged. Aliases of primitive types resolve to the aliased type (String, Integer, UUID, ...).

Tests

  • New spec oneOf_issue_25226.yaml with one oneOf per case: shared string alias, integer alias, format: uuid alias, alias of an alias, alias of an enum, direct $ref to an enum, one alias per subtype, alias inherited through allOf.
  • DefaultCodegenTest#testOneOfDiscriminatorPropertyIsRefToPrimitiveAlias (discriminator property type) and SpringCodegenTest#issue_25226 (generated interfaces and models). Both fail without the change (e.g. Shape ==> expected: <String> but was: <ShapeKind>) and pass with it.
  • ./mvnw -pl modules/openapi-generator -am test: 5361 tests, 0 failures (14 skipped, @Ignored upstream).
  • ./bin/generate-samples.sh ./bin/configs/*.yaml (all 827 configs) and ./bin/utils/export_docs_generators.sh: no change under samples/ or docs/.

PR checklist

🤖 Generated with Claude Code


Summary by cubic

Fixes #25226. When all subtypes of a oneOf use a $ref to the same alias of a primitive type as the discriminator property, the generated oneOf interface now uses the aliased type (e.g. String) instead of the missing alias schema name, which previously broke compilation. The change unaliases the schema in DefaultCodegen#getCommonSchemaType; aliases to enums and composed schemas still resolve to model names, preserving the behavior introduced in #24812.

Written for commit 0d42620. Summary will update on new commits.

View guided diff

… type

When the discriminator property of all the mapped subtypes of a oneOf is a $ref to
the same alias of a primitive type (e.g. a plain `type: string` schema),
DefaultCodegen#getCommonSchemaType returned the name of the alias schema as the
type of the discriminator getter of the oneOf interface. No model is generated for
such an alias, so the generated interface did not compile (cannot find symbol),
while the subtypes use the aliased type (e.g. String).

Unalias the schema first, like getSingleSchemaType does for the property type of
the subtypes. A $ref that is still present afterwards (enum, object, composed
schema, schema mapping) keeps being used as a model name.

Regression since 7.26.0 (OpenAPITools#24812).

fix OpenAPITools#25226

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

View guided diff | Re-trigger cubic

@Mattias-Sehlstedt

Copy link
Copy Markdown
Contributor

How does/should this play with generateAliasAsModel from https://openapi-generator.tech/docs/globals/?

@cmuchinsky

Copy link
Copy Markdown
Author

Good question. For aliases of primitive types there is no interaction: generateAliasAsModel (and x-generate-alias-as-model) only applies to array and map aliases (ModelUtils.unaliasSchema, shouldGenerateArrayModel/shouldGenerateMapModel). Primitive aliases are always flagged isAlias and never generated as models, and unaliasSchema always resolves them, so the discriminator getter gets the aliased type in both modes. I checked by generating the new spec with and without --generate-alias-as-model: identical output, no alias model.

The change delegates to unaliasSchema, so whatever the flag decides for an alias is applied to the getter, exactly as for the property type of the subtypes. For an array or map alias used as the discriminator property (not a meaningful discriminator, I only tried it to exercise the branch): with the flag the alias is a model and its name is kept (unchanged), without it the alias resolves to List/Map, which compile against the subtypes.

I can add a test that runs the new spec with the flag set if you'd like.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants