Swagger UI Infinite Recursion Issue in 3.2.0
We recently upgraded to the latest version of Connexion due to the python_multipart package issue.
connexion[swagger-ui]==3.1.0
connexion[flask]==3.1.0
to
connexion[swagger-ui]==3.2.0
connexion[flask]==3.2.0
Everything seemed to be working fine, but we can't access our Swagger UI page anymore. If we attempt to, we get a 500, and the logs show this:
INFO: 127.0.0.1:62383 - "GET /v1/ui/swagger-ui-config.json HTTP/1.1" 200 OK
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/starlette/routing.py", line 73, in app
response = await f(request)
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/connexion/middleware/swagger_ui.py", line 110, in _get_openapi_json
content=jsonifier.dumps(self._spec_for_prefix(request)),
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/connexion/middleware/swagger_ui.py", line 73, in _spec_for_prefix
return self.specification.with_base_path(base_path).raw
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/connexion/spec.py", line 221, in with_base_path
new_spec = self.clone()
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/connexion/spec.py", line 207, in clone
return type(self)(copy.deepcopy(self._spec))
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/connexion/spec.py", line 82, in __init__
self._validate_spec(raw_spec)
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/connexion/spec.py", line 96, in _validate_spec
validator.validate(spec)
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 450, in validate
for error in self.iter_errors(*args, **kwargs):
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 384, in iter_errors
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/connexion/spec.py", line 46, in validate_defaults
for error in validate_properties(validator, properties, instance, schema):
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_keywords.py", line 296, in properties
yield from validator.descend(
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_keywords.py", line 275, in ref
yield from validator._validate_reference(ref=ref, instance=instance)
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/connexion/spec.py", line 46, in validate_defaults
for error in validate_properties(validator, properties, instance, schema):
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_keywords.py", line 296, in properties
yield from validator.descend(
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_keywords.py", line 23, in patternProperties
yield from validator.descend(
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_keywords.py", line 355, in oneOf
errs = list(validator.descend(instance, subschema, schema_path=index))
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_keywords.py", line 275, in ref
yield from validator._validate_reference(ref=ref, instance=instance)
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/connexion/spec.py", line 46, in validate_defaults
for error in validate_properties(validator, properties, instance, schema):
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_keywords.py", line 296, in properties
yield from validator.descend(
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_legacy_keywords.py", line 98, in items_draft3_draft4
yield from validator.descend(item, items, path=index)
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_keywords.py", line 355, in oneOf
errs = list(validator.descend(instance, subschema, schema_path=index))
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_keywords.py", line 275, in ref
yield from validator._validate_reference(ref=ref, instance=instance)
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/connexion/spec.py", line 46, in validate_defaults
for error in validate_properties(validator, properties, instance, schema):
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_keywords.py", line 296, in properties
yield from validator.descend(
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/validators.py", line 432, in descend
for error in errors:
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_legacy_keywords.py", line 98, in items_draft3_draft4
...
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_types.py", line 116, in is_type
return fn(self, instance)
File "/Users/parthib/miniconda3/envs/backend/lib/python3.9/site-packages/jsonschema/_types.py", line 53, in is_string
return isinstance(instance, str)
[2025-01-16 15:47:20,235] INFO [Request ID: 8d0863b0-267a-44ee-bd64-cd64381cf2a1] in errors: maximum recursion depth exceeded while calling a Python object
Any ideas for the cause of the regression?
Same here, initially we thought there was an update with the openapi schema but didn't find anything suggesting that. We did find however that there was a change around jsonschema: https://github.com/spec-first/connexion/pull/1974.
Fixed our version to 3.1 until this is resolved
Looked a bit closer and found that one of my recursive schemas is the source of the infinite recursion during the json validation. Here's an idea of what the schema looks like:
Step:
oneOf:
- $ref: "#/components/schemas/Step1"
- $ref: "#/components/schemas/Step2"
components:
schemas:
BaseStep:
type: object
properties:
name:
type: string
type:
type: string
enum:
- step_1
- step_2
steps:
type: array
items:
$ref: "#/Step"
description: An optional array of nested steps.
additionalProperties: true
Step1:
allOf:
- $ref: "#/components/schemas/BaseStep"
- type: object
properties:
type:
type: string
enum:
- step_1
Step2:
allOf:
- $ref: "#/components/schemas/BaseStep"
- type: object
properties:
type:
type: string
enum:
- step_2
When I get a chance I'll try to figure out which part of the diff between v3.1 and 3.2 caused this problem to surface
Alright I narrowed it down to it being just this change that caused this issue:
https://github.com/spec-first/connexion/commit/bb48fb3e3d3866977777eb4bfcb2c4f502efd4ca
merged from this PR: https://github.com/spec-first/connexion/pull/2002
When I revert that self._spec to self._raw_spec, the validations around my self-referencing json schema pass and no longer run into a stackoverflow.
I gave it a decent try to understand what's going wrong internally in connexion, but I couldn't figure it out unfortunately. I'll just be monkey-patching connexion to revert this particular change so that we can use 3.2.0. I think @RobbeSneyders should know about the regression that change has caused though
This was fixed in PR #2089. Please reopen if there is still an issue.