openapi-spec-validator icon indicating copy to clipboard operation
openapi-spec-validator copied to clipboard

Possible Regression: RecursionError validating oneOf/allOf schema in 0.7.2 (works in 0.7.1)

Open sammasak opened this issue 6 months ago • 1 comments

Summary

An OpenAPI 3.1 schema that validated fine with openapi-spec-validator 0.7.1 now fails with a RecursionError in 0.7.2

Environment

openapi-spec-validator | 0.7.2 ❌ / 0.7.1 ✅ uv 0.7.3 (3c413f74b 2025-05-07)

Minimal reproduction

# validate.py
# /// script
# requires-python = ">=3.12"
# dependencies = [
#    "openapi-spec-validator==0.7.2" # TODO: test with 0.7.1
# ]
# ///


import yaml
from openapi_spec_validator import validate

openapi_spec = """
openapi: 3.1.0
info:
  title: Recursion Bug Demo
  version: 0.1.0
components:
  schemas:
    PropertyConstraint:
      type: object
      oneOf:
        - $ref: '#/components/schemas/PropertyEqualityConstraint'
        - $ref: '#/components/schemas/PropertyRangeConstraint'
      properties:
        property_id:
          type: string
        type:
          type: string
      required: [type]

    PropertyEqualityConstraint:
      allOf:
        - $ref: '#/components/schemas/PropertyConstraint'
        - type: object
          properties:
            property_id:
              type: string
            property_value: {}
          required: [property_id, property_value]

    PropertyRangeConstraint:
      allOf:
        - $ref: '#/components/schemas/PropertyConstraint'
        - type: object
          properties:
            property_id:
              type: string
            min: {}
            max: {}
          required: [property_id, min, max]
"""


parsed_spec = yaml.safe_load(openapi_spec)
validate(parsed_spec)
print("valid")

> uv run validate.py
RecursionError: maximum recursion depth exceeded

Set the version to 0.7.1 in the uv script tag at the top.

> uv run validate.py
valid

Has anyone else observed this behaviour?

sammasak avatar Jun 10 '25 13:06 sammasak

@tembleking It appears that #391 (released in v0.7.2) will recurse until Python raises an exception.

Would you review this bug report and consider how to prevent this?

For example, perhaps it would be possible to have a default argument like max_depth=5 attached to the ._collect_properties() method that is decremented each time the method calls itself.

kurtmckee avatar Jun 26 '25 12:06 kurtmckee