Skip to content

[normalizer] Preserve AnyType for typeless OAS 3.0 schemas in referenced files - #25414

Open
josephaxisa wants to merge 3 commits into
OpenAPITools:masterfrom
josephaxisa:fix/normalizer-external-typeless-schema
Open

josephaxisa wants to merge 3 commits into
OpenAPITools:masterfrom
josephaxisa:fix/normalizer-external-typeless-schema

Conversation

@josephaxisa

@josephaxisa josephaxisa commented Oct 25, 2026 •

Copy link
Copy Markdown

Fixes #25412

Summary

When an OpenAPI 3.0 specification references an external file (such as a PathItem, ApiResponse, Parameter, RequestBody, or a whole-file schema $ref such as sailpoint-oss/api-specs), swagger-parser's ResolverCache.loadRef deserializes the external node via Jackson (ModelDeserializer). Because ModelDeserializer.useArbitrarySchema defaults to false, ModelDeserializer.deserializeArbitraryOrObjectSchema instantiates typeless schemas (description: ... with no type, properties, or additionalProperties) as ObjectSchema (type: "object"), while storing the raw parsed JSON/YAML map in schema.getJsonSchema() (where !schema.getJsonSchema().containsKey("type")).
By contrast, the same typeless schema in the root OpenAPI 3.0 document is parsed by OpenAPIDeserializer via SchemaTypeUtil.createSchemaByType(node) into a base Schema instance (type == null), which OpenAPI Generator maps to AnyType.

Changes

  • OpenAPINormalizer.java:
    • In normalizeSimpleSchema(Schema schema, Set<Schema> visitedSchemas) (reached only after confirming the schema is not an array, not a ComposedSchema, has no properties, and has no Schema additionalProperties), check whether an ObjectSchema has a raw jsonSchema map without "type" or "properties" keys and no object-specific constraints (schema instanceof ObjectSchema && schema.getJsonSchema() != null && !schema.getJsonSchema().containsKey("type") && !schema.getJsonSchema().containsKey("properties") && schema.getProperties() == null && schema.getAdditionalProperties() == null && schema.getRequired() == null && schema.getMinProperties() == null && schema.getMaxProperties() == null && schema.getPatternProperties() == null && schema.getDiscriminator() == null && schema.getEnum() == null) and convert it to a base new Schema<>() (type == null) with metadata and validation fields copied via ModelUtils.copyMetadata(schema, sc) (plus pattern, format, multipleOf, uniqueItems, exclusiveMinimum, exclusiveMaximum, exclusiveMinimumValue, exclusiveMaximumValue, not, xml, externalDocs, and jsonSchema), matching the OAS 3.1 AnyType handling in processNormalize31Spec.
    • In normalizeSchema's array and map branches, assign result.setItems(normalizeSchema(result.getItems(), visitedSchemas)) and result.setAdditionalProperties(normalized) so normalized array items and map additionalProperties schemas are not discarded.
  • OpenAPINormalizerTest.java:
    • Real-world multi-file spec check (sailpoint-oss/api-specs, OAS 3.0): Verified against referenced PathItem schemas that omit type for arbitrary variable values. Resolved schemas and generated Python models now preserve AnyType instead of coercing to type: object.
    • Add testTypelessSchemaInReferencedFileRemainsAnyType verifying that typeless schemas in referenced files (via a PathItem response, a whole-file schema $ref, and an array items $ref) normalize to AnyType (type == null, isObjectSchema == false, isFreeFormObject == false) while explicit type: object and required: [id] schemas in referenced files preserve their object semantics and constraints.
      cc @OpenAPITools/generator-core-team

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@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.

All reported issues were addressed across 2 files

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

@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.

All reported issues were addressed across 1 file (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

@josephaxisa

Copy link
Copy Markdown
Author

cc @wing328, I updated to ensure Swagger 2.0 converted specs and existing generator samples remain untouched

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

Development

Successfully merging this pull request may close these issues.

[BUG][normalizer] Typeless OAS 3.0 schemas in referenced files are coerced to type: object

1 participant