mirror of
https://github.com/open-webui/open-webui.git
synced 2026-05-06 19:08:59 -05:00
[GH-ISSUE #23543] issue: Open WebUI crashes with RecursionError when Tool Server OpenAPI spec contains circular $ref schemas #35538
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @stepek on GitHub (Apr 9, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/23543
Check Existing Issues
Installation Method
Git Clone
Open WebUI Version
0.8.12
Ollama Version (if applicable)
No response
Operating System
ubuntu 22.04
Browser (if applicable)
No response
Confirmation
README.md.Expected Behavior
When configuring a Tool Server whose OpenAPI specification contains circular $ref references (e.g. a schema that references itself through a nested property), Open WebUI should gracefully handle the recursive schema resolution — either by detecting the cycle and stopping, or by limiting the resolution depth. The /api/v1/tools/ endpoint should return successfully and all configured Tool Servers should remain functional.
Actual Behavior
The resolve_schema function in /app/backend/open_webui/utils/tools.py enters infinite recursion when encountering a self-referencing $ref in the OpenAPI spec. This causes a RecursionError that crashes the entire /api/v1/tools/ endpoint with HTTP 500, making all configured Tool Servers unavailable — not just the one with the circular schema.
Steps to Reproduce
1Set up an external API that exposes an OpenAPI 3.x spec containing a circular $ref, for example a schema like:
2In Open WebUI Admin settings, add this API as a Tool Server connection by providing its OpenAPI spec URL.
3Navigate to any page that triggers a call to GET /api/v1/tools/.
4Observe that the request fails with HTTP 500 and the logs show a RecursionError with repeated frames in resolve_schema at lines 707, 714, and 717 of tools.py.
5Note that all other Tool Servers also become inaccessible because the error aborts the entire get_tool_servers_data call.
Logs & Screenshots
2026-04-09 12:00:15.035 | INFO | uvicorn.protocols.http.httptools_impl:send:483 - 10.116.4.1:0 - "GET /api/v1/tools/ HTTP/1.1" 500
| File "/usr/local/lib/python3.12/site-packages/starlette/_utils.py", line 81, in collapse_excgroups
| yield
| File "/usr/local/lib/python3.12/site-packages/starlette/middleware/base.py", line 192, in call
| async with anyio.create_task_group() as task_group:
| File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 799, in aexit
| raise BaseExceptionGroup(
| ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "/app/backend/open_webui/routers/tools.py", line 86, in get_tools
| for server in await get_tool_servers(request):
| File "/app/backend/open_webui/utils/tools.py", line 813, in get_tool_servers
| tool_servers = await set_tool_servers(request)
| File "/app/backend/open_webui/utils/tools.py", line 795, in set_tool_servers
| request.app.state.TOOL_SERVERS = await get_tool_servers_data(request.app.state.config.TOOL_SERVER_CONNECTIONS)
| File "/app/backend/open_webui/utils/tools.py", line 1164, in get_tool_servers_data
| 'specs': convert_openapi_to_tool_payload(response),
| File "/app/backend/open_webui/utils/tools.py", line 778, in convert_openapi_to_tool_payload
| resolved_schema = resolve_schema(json_schema, openapi_spec.get('components', {}))
| File "/app/backend/open_webui/utils/tools.py", line 707, in resolve_schema
| return resolve_schema(resolved, components)
| File "/app/backend/open_webui/utils/tools.py", line 714, in resolve_schema
| resolved_schema['properties'][prop] = resolve_schema(prop_schema, components)
| File "/app/backend/open_webui/utils/tools.py", line 717, in resolve_schema
| resolved_schema['items'] = resolve_schema(resolved_schema['items'], components)
| File "/app/backend/open_webui/utils/tools.py", line 707, in resolve_schema
| return resolve_schema(resolved, components)
| File "/app/backend/open_webui/utils/tools.py", line 714, in resolve_schema
| resolved_schema['properties'][prop] = resolve_schema(prop_schema, components)
| File "/app/backend/open_webui/utils/tools.py", line 717, in resolve_schema
| resolved_schema['items'] = resolve_schema(resolved_schema['items'], components)
|
| ... (repeating ~200+ times until RecursionError)
Additional Information
No response
@tjbck commented on GitHub (Apr 12, 2026):
Should be addressed in dev.