mirror of
https://github.com/open-webui/open-webui.git
synced 2026-09-02 03:59:45 +02:00
fix: resolve circular OpenAPI schema refs in tool server specs (#27413)
OpenAPI specs with circular schema references, such as Mealie's where Recipe and RecipeCategory reference each other through properties and array items, crashed convert_openapi_to_tool_payload with a RecursionError, so the tool server produced no specs and the integration never appeared in the model or tool selection. resolve_schema already had a visited-set guard against circular references, but the recursive calls for properties and items dropped the set, so cycles running through those edges were never detected. This threads the visited set through those calls and passes a per-path copy when following a $ref, so only true ancestor cycles are pruned to an empty schema while sibling references to the same schema still resolve fully. Fixes #27239.
This commit is contained in:
@@ -913,23 +913,22 @@ def resolve_schema(schema, components, resolved_schemas=None):
|
||||
# Avoid infinite recursion on circular references
|
||||
return {}
|
||||
|
||||
resolved_schemas.add(schema_name)
|
||||
|
||||
ref_parts = ref_path.strip('#/').split('/')
|
||||
resolved = components
|
||||
for part in ref_parts[1:]: # Skip the initial 'components'
|
||||
resolved = resolved.get(part, {})
|
||||
return resolve_schema(resolved, components, resolved_schemas)
|
||||
# Per-path visited set so sibling refs to the same schema still resolve
|
||||
return resolve_schema(resolved, components, resolved_schemas | {schema_name})
|
||||
|
||||
resolved_schema = copy.deepcopy(schema)
|
||||
|
||||
# Recursively resolve inner schemas
|
||||
if 'properties' in resolved_schema:
|
||||
for prop, prop_schema in resolved_schema['properties'].items():
|
||||
resolved_schema['properties'][prop] = resolve_schema(prop_schema, components)
|
||||
resolved_schema['properties'][prop] = resolve_schema(prop_schema, components, resolved_schemas)
|
||||
|
||||
if 'items' in resolved_schema:
|
||||
resolved_schema['items'] = resolve_schema(resolved_schema['items'], components)
|
||||
resolved_schema['items'] = resolve_schema(resolved_schema['items'], components, resolved_schemas)
|
||||
|
||||
# Resolve composition keywords (oneOf, anyOf, allOf) which may contain $ref
|
||||
for keyword in ('oneOf', 'anyOf', 'allOf'):
|
||||
|
||||
Reference in New Issue
Block a user