[GH-ISSUE #23907] bug: native function_calling on custom model variant not forwarded to Ollama (v0.8.12) #58770

Closed
opened 2026-05-05 23:52:24 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @rromenskyi on GitHub (Apr 21, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/23907

Summary

On Open WebUI v0.8.12 (latest at time of writing, :main / :latest on GHCR), a custom model variant created in Workspace → Models with function_calling: native persisted in its params causes the model to receive no tools despite the server having a registered MCP / OpenAPI tool server. The frontend UI appears to honour the setting (the integrations menu shows the registered tools) but the request that ultimately reaches Ollama carries no tools: [...] array, so the model never emits tool_calls.

A direct POST /api/chat to the same Ollama instance with the exact tools array returns correct tool_calls, so the model and the tool descriptions are fine — the break is in Open WebUI's middleware path for custom variants.

Reproducer

  1. Fresh Open WebUI 0.8.12 pod (bundled Ollama unimportant; I'm using an external Ollama).
  2. Pull a tool-calling model:
    ollama pull qwen2.5:7b
    
  3. Register a tool server. MCP type (streamable HTTP) works, plain OpenAPI works too. Any catalog with a weather-ish tool named, say, get_current_weather_in_city(city: str) is fine.
  4. Admin → Settings → External Tools → Verify → Save. Confirm the tool shows up in the catalog.
  5. Workspace → Models → Create a variant of qwen2.5:7b called qwen2.5:7b+tools. In the edit form:
    • System prompt: anything encouraging tool use.
    • Advanced Params → Function Calling: Native.
    • Save.
  6. Verify the saved state with a DB dump:
    import sqlite3, json
    c = sqlite3.connect("/app/backend/data/webui.db")
    row = c.execute("SELECT params FROM model WHERE id='qwen257btools'").fetchone()
    print(json.loads(row[0]))
    # → {"system": "...", "function_calling": "native"}
    
  7. Start a new chat with qwen2.5:7b+tools, ask "What is the current weather in Bountiful, Utah?".

Expected

Model emits a tool_calls: [{function: {name: "get_current_weather_in_city", arguments: {city: "Bountiful, Utah"}}}], Open WebUI invokes the tool, response shows the actual weather.

Actual

Model replies with plaintext explaining how the user could run curl wttr.in/... or similar. No tool is called. Backend logs show:

POST /api/chat/completions 200
# MCP sidecar log: 1 ListToolsRequest, 0 CallToolRequest

So Open WebUI fetches the tool list from the registered MCP server (confirming registration works) but the model never generates a tool_call.

Evidence this is an OWUI bug, not Ollama/model

Same Ollama instance, same model, same tool definitions — sent directly:

curl -X POST http://ollama/api/chat -d '{
  "model": "qwen2.5:7b",
  "messages": [{"role":"user","content":"What is the current weather in Bountiful, Utah?"}],
  "tools": [{
    "type":"function",
    "function":{
      "name":"get_current_weather_in_city",
      "description":"Get the current weather for a city or postal code.",
      "parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}
    }
  }],
  "stream": false,
  "options": {"temperature": 0}
}'

Returns:

{
  "message": {
    "content": "",
    "tool_calls": [{
      "id": "call_27wkzuet",
      "function": {
        "name": "get_current_weather_in_city",
        "arguments": {"city": "Bountiful, Utah"}
      }
    }]
  }
}

So qwen2.5:7b + Ollama + the exact tool spec work perfectly when the tools array reaches them. OWUI is dropping the array somewhere.

Code path

main.py:1728-1735 sets metadata.params.function_calling = 'native' when either form_data.params.function_calling == 'native' OR model_info_params.function_calling == 'native'. The OR branch should pick up the custom-variant setting.

utils/middleware.py:2678 then reads metadata.params.function_calling == 'native' and sets form_data['tools'] = [...] from tools_dict.

tools_dict is non-empty (ListToolsRequest confirms MCP server was consulted), and function_calling: native is saved in the variant. So either:

  • metadata.params.function_calling is not reaching middleware.py:2678 as 'native', or
  • tools_dict is empty at that point despite the earlier ListToolsRequest.

I haven't fully traced which.

Workarounds

  • Using a raw POST /api/chat/completions with explicit tools in form_data.params (per-request Native override from Chat Controls) sometimes works, sometimes doesn't — seems chat-session-state dependent.
  • Skipping OWUI entirely and driving Ollama + the MCP server via mcphost works without issue — same model, same tools, same prompts.

Version details

  • Open WebUI: ghcr.io/open-webui/open-webui:main @ sha256:a10c18cd35fa9bcaa7650598c1699609db1292ce4fc89499b5eaf93ac435f380 (v0.8.12, 2026-03-27)
  • Ollama: standalone latest, external
  • Model: qwen2.5:7b (also tried qwen2.5:14b, qwen2.5-coder:7b — same behaviour)
  • Tool server: MCP streamable-HTTP from mcp-weather-simple, tools/list returns 21 tool specs

dev branch is on 0.9.0 — if the fix is already there, happy to re-test once published on GHCR as :dev or similar. Right now only :main and git-<sha> tags of 0.8.12 are available.

Thanks!

Originally created by @rromenskyi on GitHub (Apr 21, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/23907 ## Summary On Open WebUI **v0.8.12** (latest at time of writing, `:main` / `:latest` on GHCR), a custom model variant created in `Workspace → Models` with `function_calling: native` persisted in its `params` causes the model to receive **no tools** despite the server having a registered MCP / OpenAPI tool server. The frontend UI appears to honour the setting (the integrations menu shows the registered tools) but the request that ultimately reaches Ollama carries no `tools: [...]` array, so the model never emits `tool_calls`. A direct `POST /api/chat` to the same Ollama instance with the exact tools array returns correct `tool_calls`, so the model and the tool descriptions are fine — the break is in Open WebUI's middleware path for custom variants. ## Reproducer 1. Fresh Open WebUI 0.8.12 pod (bundled Ollama unimportant; I'm using an external Ollama). 2. Pull a tool-calling model: ``` ollama pull qwen2.5:7b ``` 3. Register a tool server. MCP type (streamable HTTP) works, plain OpenAPI works too. Any catalog with a weather-ish tool named, say, `get_current_weather_in_city(city: str)` is fine. 4. `Admin → Settings → External Tools → Verify → Save`. Confirm the tool shows up in the catalog. 5. `Workspace → Models → Create` a variant of `qwen2.5:7b` called `qwen2.5:7b+tools`. In the edit form: - System prompt: anything encouraging tool use. - Advanced Params → Function Calling: **Native**. - Save. 6. Verify the saved state with a DB dump: ```python import sqlite3, json c = sqlite3.connect("/app/backend/data/webui.db") row = c.execute("SELECT params FROM model WHERE id='qwen257btools'").fetchone() print(json.loads(row[0])) # → {"system": "...", "function_calling": "native"} ``` 7. Start a new chat with `qwen2.5:7b+tools`, ask **"What is the current weather in Bountiful, Utah?"**. ## Expected Model emits a `tool_calls: [{function: {name: "get_current_weather_in_city", arguments: {city: "Bountiful, Utah"}}}]`, Open WebUI invokes the tool, response shows the actual weather. ## Actual Model replies with plaintext explaining how the user could run `curl wttr.in/...` or similar. No tool is called. Backend logs show: ``` POST /api/chat/completions 200 # MCP sidecar log: 1 ListToolsRequest, 0 CallToolRequest ``` So Open WebUI fetches the tool list from the registered MCP server (confirming registration works) but the model never generates a tool_call. ## Evidence this is an OWUI bug, not Ollama/model Same Ollama instance, same model, same tool definitions — sent directly: ```bash curl -X POST http://ollama/api/chat -d '{ "model": "qwen2.5:7b", "messages": [{"role":"user","content":"What is the current weather in Bountiful, Utah?"}], "tools": [{ "type":"function", "function":{ "name":"get_current_weather_in_city", "description":"Get the current weather for a city or postal code.", "parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]} } }], "stream": false, "options": {"temperature": 0} }' ``` Returns: ```json { "message": { "content": "", "tool_calls": [{ "id": "call_27wkzuet", "function": { "name": "get_current_weather_in_city", "arguments": {"city": "Bountiful, Utah"} } }] } } ``` So qwen2.5:7b + Ollama + the exact tool spec work perfectly when the `tools` array reaches them. OWUI is dropping the array somewhere. ## Code path `main.py:1728-1735` sets `metadata.params.function_calling = 'native'` when either `form_data.params.function_calling == 'native'` OR `model_info_params.function_calling == 'native'`. The OR branch should pick up the custom-variant setting. `utils/middleware.py:2678` then reads `metadata.params.function_calling == 'native'` and sets `form_data['tools'] = [...]` from `tools_dict`. `tools_dict` is non-empty (ListToolsRequest confirms MCP server was consulted), and `function_calling: native` is saved in the variant. So either: - `metadata.params.function_calling` is not reaching middleware.py:2678 as `'native'`, or - `tools_dict` is empty at that point despite the earlier ListToolsRequest. I haven't fully traced which. ## Workarounds - Using a raw `POST /api/chat/completions` with explicit `tools` in `form_data.params` (per-request Native override from Chat Controls) sometimes works, sometimes doesn't — seems chat-session-state dependent. - Skipping OWUI entirely and driving Ollama + the MCP server via [`mcphost`](https://github.com/mark3labs/mcphost) works without issue — same model, same tools, same prompts. ## Version details - Open WebUI: `ghcr.io/open-webui/open-webui:main` @ `sha256:a10c18cd35fa9bcaa7650598c1699609db1292ce4fc89499b5eaf93ac435f380` (v0.8.12, 2026-03-27) - Ollama: standalone latest, external - Model: `qwen2.5:7b` (also tried `qwen2.5:14b`, `qwen2.5-coder:7b` — same behaviour) - Tool server: MCP streamable-HTTP from [`mcp-weather-simple`](https://github.com/rromenskyi/mcp-weather-simple), `tools/list` returns 21 tool specs `dev` branch is on 0.9.0 — if the fix is already there, happy to re-test once published on GHCR as `:dev` or similar. Right now only `:main` and `git-<sha>` tags of 0.8.12 are available. Thanks!
Author
Owner

@pr-validator-bot commented on GitHub (Apr 21, 2026):

⚠️ Missing Issue Title Prefix

@rromenskyi, your issue title is missing a prefix (e.g., bug:, feat:, docs:).

Please update your issue title to include one of the following prefixes:

  • bug: Bug report or error you've encountered
  • feat: Feature request or enhancement suggestion
  • docs: Documentation issue or improvement request
  • question: Question about usage or functionality
  • help: Request for help or support

Example: bug: Login fails when using special characters in password

<!-- gh-comment-id:4285845904 --> @pr-validator-bot commented on GitHub (Apr 21, 2026): # ⚠️ Missing Issue Title Prefix @rromenskyi, your issue title is missing a prefix (e.g., `bug:`, `feat:`, `docs:`). Please update your issue title to include one of the following prefixes: - **bug**: Bug report or error you've encountered - **feat**: Feature request or enhancement suggestion - **docs**: Documentation issue or improvement request - **question**: Question about usage or functionality - **help**: Request for help or support Example: `bug: Login fails when using special characters in password`
Author
Owner

@tjbck commented on GitHub (Apr 21, 2026):

Unable to reproduce, did you enable the tool in the UI specifically?

<!-- gh-comment-id:4285991531 --> @tjbck commented on GitHub (Apr 21, 2026): Unable to reproduce, did you enable the tool in the UI specifically?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#58770