[GH-ISSUE #24930] issue: DEFAULT_MODEL_PARAMS (admin "Default Parameters") not applied to outbound payloads — only OWUI-internal flags inherit, sampling params like max_tokens are silently dropped #123745

Open
opened 2026-05-21 03:14:10 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @ryan-pip on GitHub (May 20, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/24930

Check Existing Issues

  • I have searched for any existing and/or related issues.
  • I have searched for any existing and/or related discussions.
  • I have also searched in the CLOSED issues AND CLOSED discussions and found no related items (your issue might already be addressed on the development branch!).
  • I am using the latest version of Open WebUI.

Searched terms include DEFAULT_MODEL_PARAMS, default parameters max_tokens, default model params, max_tokens not applied, default sampling params, apply_model_params_to_body, model_info_params, global default ignored. Closest existing reports are not duplicates:

  • #21837 / discussion #21839DEFAULT_MODEL_PARAMS ignored when set via env var with ENABLE_PERSISTENT_CONFIG=false (env-parse path, different code path; in this report the value IS persisted and visible via /api/v1/configs/export).
  • #19214 — chat-control overrides being beaten by per-model admin defaults (precedence inversion, opposite direction; in this report the per-chat overrides do work — only the global default is dropped).
  • #17131 — per-user "Settings → Advanced Parameters" sending args that break some models (different UI surface, different field on the config).
  • Discussion #8368 — user-settings context limit not applied to Ollama (v0.5.4, user-level not admin-level, only Ollama).

Installation Method

Docker

Open WebUI Version

main (verified against current HEAD d47c88f, 2026-05-20). The bug is also present in the latest release v0.9.5.

Ollama Version (if applicable)

Not applicable — bug is server-side and reproducible against any OpenAI-compatible upstream that honours max_tokens. The Ollama router has the same shape and is likely affected (see "Logs & Code references" below).

Operating System

Not OS-dependent — bug is in backend/open_webui Python code.

Browser (if applicable)

Not applicable — bug is server-side. Outbound chat-completion request payload is wrong regardless of client.

Confirmation

  • I have read and followed all instructions in README.md.
  • I am using the latest version of both Open WebUI and Ollama.
  • I have included the browser console logs.
  • I have included the Docker container logs.
  • I have provided every relevant configuration, setting, and environment variable used in my setup.
  • I have clearly listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc).
  • I have documented step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation.

Relevant configuration: DEFAULT_MODEL_PARAMS set via the admin UI ("Settings → Models → Default Parameters"), persisted to the config table (visible via /api/v1/configs/export as models.default_params.*). No env-var overrides for DEFAULT_MODEL_PARAMS. The active model's stored info.params JSON does NOT contain a max_tokens key (only e.g. function_calling, custom_params). Provider is an OpenAI-compatible endpoint (also reproduces against Amazon Bedrock via the bedrock-access-gateway, which simply forwards max_tokens).

Expected Behavior

Setting Default Parameters → max_tokens in the admin UI should apply that value to outbound chat-completion requests for any model whose own params object does not specify max_tokens. The intuitive precedence (which the admin UI implies) is:

per-chat override  >  per-model `params`  >  global `DEFAULT_MODEL_PARAMS`  >  hardcoded fallback

This should hold for all provider sampling parameters: max_tokens, temperature, top_p, top_k, frequency_penalty, presence_penalty, seed, stop, etc.

Actual Behavior

The global default is persisted correctly and even merged into an in-memory model_info_params dict in main.py, but the merged dict is then only consulted for four Open WebUI-internal flags (stream_response, stream_delta_chunk_size, reasoning_tags, function_calling). Every provider sampling parameter — including max_tokens — is dropped on the floor because the OpenAI router (and the Ollama router) reads model_info.params directly instead of the merged dict.

Net effect: the admin "Default Parameters" form looks like it works (the value is persisted, the export endpoint confirms it, the UI shows it), but for max_tokens/temperature/etc. it is dead code on the OpenAI path. Outbound requests go out with Open WebUI's hardcoded fallback (max_tokens: 2048 via apply_model_params_to_body_openai) unless the per-model info.params or per-chat controls explicitly set the field.

The user-visible symptom: long responses are truncated mid-stream (e.g. mid-tool-call when emitting large structured outputs) because the model only generates 2048 tokens, despite the admin having set max_tokens: 128000 globally.

Steps to Reproduce

  1. Start a fresh Open WebUI deployment on main (or v0.9.5) backed by any OpenAI-compatible provider that honours max_tokens (OpenAI itself, Azure OpenAI, Bedrock via bedrock-access-gateway, vLLM, LM Studio, etc.). No special config required — defaults.
  2. Sign in as an admin. Go to Settings → Models → Default Parameters (the global form, not a per-model form). Set max_tokens to a recognisable value, e.g. 99999. Save.
  3. Confirm persistence: curl -H "Authorization: Bearer $TOKEN" https://<host>/api/v1/configs/export | jq '.models.default_params.max_tokens' → returns 99999. (The config IS saved correctly; this rules out persistence bugs like #21837.)
  4. Pick a model whose Workspace → Models entry has NO max_tokens in its params JSON (the default for any model that hasn't been edited). Optionally inspect via GET /api/v1/models/<id>.
  5. Start a new chat with that model. Do NOT open chat controls. Do NOT change anything. Just send a prompt that should generate a long response (e.g. "List 100 prime numbers with explanations").
  6. Capture the outbound provider request — either via a logging proxy in front of the upstream, or by adding a temporary log line in apply_model_params_to_body_openai / before aiohttp_client_session.post(...) in routers/openai.py. Observe "max_tokens": 2048 in the JSON payload (Open WebUI's hardcoded default), NOT 99999.
  7. As a control, open chat controls and explicitly set max_tokens to 50000 for the chat. Send another prompt. Observe "max_tokens": 50000 in the outbound request — confirming the per-chat override path works fine and isolating the bug to the global default fallback.
  8. As a second control, edit the model in Workspace → Models and add max_tokens: 77777 to its params. Start a new chat (no chat-control override). Observe "max_tokens": 77777 — confirming the per-model path also works.

The bug is specifically: per-chat override works, per-model params works, but the global DEFAULT_MODEL_PARAMS fallback for sampling params does NOT work on the OpenAI path. Same trace on the Ollama path.

Logs & Screenshots

Code trace against main at commit d47c88f (2026-05-20):

1. backend/open_webui/main.py:1709-1713 — the merge IS built with the correct precedence:

# Model params: global defaults as base, per-model overrides win
default_model_params = getattr(request.app.state.config, 'DEFAULT_MODEL_PARAMS', None) or {}
model_info_params = {
    **default_model_params,
    **(model_info.params.model_dump() if model_info and model_info.params else {}),
}

2. backend/open_webui/main.py:1738-1791 — but model_info_params is then ONLY consulted for four keys: stream_response, stream_delta_chunk_size, reasoning_tags, function_calling. Provider sampling params (max_tokens, temperature, top_p, etc.) are never read off the merged dict; the merged dict is dropped after this block.

3. backend/open_webui/routers/openai.py:1115 — the outbound payload builder reads model_info.params directly (NOT the merged dict from step 1):

params = model_info.params.model_dump()
if params:
    system = params.pop('system', None)
    payload = apply_model_params_to_body_openai(params, payload)

So the global default fallback computed in main.py never reaches the OpenAI payload builder.

4. backend/open_webui/routers/ollama.pyparams = model_info.params.model_dump() appears at lines 1123, 1216, 1279 with the same shape. The Ollama path almost certainly has the same bug. (Not verified end-to-end against a live Ollama instance, but the source pattern is identical.)

5. backend/open_webui/utils/payload.py::apply_model_params_to_body_openai confirms there's no internal fallback to a global default either — it just copies the provided dict's keys into form_data, falling back to Open WebUI's own hardcoded defaults (e.g. max_tokens: 2048) when a key is absent.

Browser console logs and Docker container logs are not informative for this bug — it's a server-side payload-construction bug, evidenced entirely by inspecting the outbound request body sent to the upstream provider.

Additional Information

Proposed fix: change routers/openai.py:1115 (and the three analogous sites in routers/ollama.py) to consume the merged model_info_params already computed in main.py rather than re-deriving from raw model_info.params. Either:

  • Plumb the merged dict through payload['metadata'] (already used to pass other per-request context) and use it in the router; or
  • Move the merge into the router itself, by reading request.app.state.config.DEFAULT_MODEL_PARAMS before the call to apply_model_params_to_body_openai and merging it underneath the per-model dict; or
  • Have apply_model_params_to_body_openai accept a default_params: dict | None argument and apply it as a base layer before the per-model overrides.

Whichever shape is preferred, the contract should be that DEFAULT_MODEL_PARAMS is a true base layer for every provider sampling param, not just the four Open WebUI-internal flags currently consulted in main.py. That matches what the admin UI implies and what users reasonably expect from a "Default Parameters" form. Happy to send a PR if a maintainer can confirm a preferred shape.

Originally created by @ryan-pip on GitHub (May 20, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/24930 ### Check Existing Issues - [x] I have searched for any existing and/or related issues. - [x] I have searched for any existing and/or related discussions. - [x] I have also searched in the CLOSED issues AND CLOSED discussions and found no related items (your issue might already be addressed on the development branch!). - [x] I am using the latest version of Open WebUI. Searched terms include `DEFAULT_MODEL_PARAMS`, `default parameters max_tokens`, `default model params`, `max_tokens not applied`, `default sampling params`, `apply_model_params_to_body`, `model_info_params`, `global default ignored`. Closest existing reports are not duplicates: - #21837 / discussion #21839 — `DEFAULT_MODEL_PARAMS` ignored when set via env var with `ENABLE_PERSISTENT_CONFIG=false` (env-parse path, different code path; in this report the value IS persisted and visible via `/api/v1/configs/export`). - #19214 — chat-control overrides being beaten by per-model admin defaults (precedence inversion, opposite direction; in this report the per-chat overrides do work — only the global default is dropped). - #17131 — per-user "Settings → Advanced Parameters" sending args that break some models (different UI surface, different field on the config). - Discussion #8368 — user-settings context limit not applied to Ollama (v0.5.4, user-level not admin-level, only Ollama). ### Installation Method Docker ### Open WebUI Version `main` (verified against current HEAD `d47c88f`, 2026-05-20). The bug is also present in the latest release v0.9.5. ### Ollama Version (if applicable) Not applicable — bug is server-side and reproducible against any OpenAI-compatible upstream that honours `max_tokens`. The Ollama router has the same shape and is likely affected (see "Logs & Code references" below). ### Operating System Not OS-dependent — bug is in `backend/open_webui` Python code. ### Browser (if applicable) Not applicable — bug is server-side. Outbound chat-completion request payload is wrong regardless of client. ### Confirmation - [x] I have read and followed all instructions in `README.md`. - [x] I am using the latest version of **both** Open WebUI and Ollama. - [x] I have included the browser console logs. - [x] I have included the Docker container logs. - [x] I have **provided every relevant configuration, setting, and environment variable used in my setup.** - [x] I have clearly **listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup** (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc). - [x] I have documented **step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation**. Relevant configuration: `DEFAULT_MODEL_PARAMS` set via the admin UI ("Settings → Models → Default Parameters"), persisted to the config table (visible via `/api/v1/configs/export` as `models.default_params.*`). No env-var overrides for `DEFAULT_MODEL_PARAMS`. The active model's stored `info.params` JSON does NOT contain a `max_tokens` key (only e.g. `function_calling`, `custom_params`). Provider is an OpenAI-compatible endpoint (also reproduces against Amazon Bedrock via the bedrock-access-gateway, which simply forwards `max_tokens`). ### Expected Behavior Setting `Default Parameters → max_tokens` in the admin UI should apply that value to outbound chat-completion requests for any model whose own `params` object does not specify `max_tokens`. The intuitive precedence (which the admin UI implies) is: ``` per-chat override > per-model `params` > global `DEFAULT_MODEL_PARAMS` > hardcoded fallback ``` This should hold for all provider sampling parameters: `max_tokens`, `temperature`, `top_p`, `top_k`, `frequency_penalty`, `presence_penalty`, `seed`, `stop`, etc. ### Actual Behavior The global default is persisted correctly and even merged into an in-memory `model_info_params` dict in `main.py`, but the merged dict is then only consulted for four Open WebUI-internal flags (`stream_response`, `stream_delta_chunk_size`, `reasoning_tags`, `function_calling`). Every provider sampling parameter — including `max_tokens` — is dropped on the floor because the OpenAI router (and the Ollama router) reads `model_info.params` directly instead of the merged dict. Net effect: the admin "Default Parameters" form looks like it works (the value is persisted, the export endpoint confirms it, the UI shows it), but for `max_tokens`/`temperature`/etc. it is **dead code on the OpenAI path**. Outbound requests go out with Open WebUI's hardcoded fallback (`max_tokens: 2048` via `apply_model_params_to_body_openai`) unless the per-model `info.params` or per-chat controls explicitly set the field. The user-visible symptom: long responses are truncated mid-stream (e.g. mid-tool-call when emitting large structured outputs) because the model only generates 2048 tokens, despite the admin having set `max_tokens: 128000` globally. ### Steps to Reproduce 1. Start a fresh Open WebUI deployment on `main` (or v0.9.5) backed by any OpenAI-compatible provider that honours `max_tokens` (OpenAI itself, Azure OpenAI, Bedrock via bedrock-access-gateway, vLLM, LM Studio, etc.). No special config required — defaults. 2. Sign in as an admin. Go to **Settings → Models → Default Parameters** (the global form, not a per-model form). Set `max_tokens` to a recognisable value, e.g. `99999`. Save. 3. Confirm persistence: `curl -H "Authorization: Bearer $TOKEN" https://<host>/api/v1/configs/export | jq '.models.default_params.max_tokens'` → returns `99999`. (The config IS saved correctly; this rules out persistence bugs like #21837.) 4. Pick a model whose Workspace → Models entry has NO `max_tokens` in its `params` JSON (the default for any model that hasn't been edited). Optionally inspect via `GET /api/v1/models/<id>`. 5. Start a **new chat** with that model. Do NOT open chat controls. Do NOT change anything. Just send a prompt that should generate a long response (e.g. "List 100 prime numbers with explanations"). 6. Capture the outbound provider request — either via a logging proxy in front of the upstream, or by adding a temporary log line in `apply_model_params_to_body_openai` / before `aiohttp_client_session.post(...)` in `routers/openai.py`. Observe `"max_tokens": 2048` in the JSON payload (Open WebUI's hardcoded default), NOT `99999`. 7. As a control, open chat controls and explicitly set `max_tokens` to `50000` for the chat. Send another prompt. Observe `"max_tokens": 50000` in the outbound request — confirming the per-chat override path works fine and isolating the bug to the *global default* fallback. 8. As a second control, edit the model in Workspace → Models and add `max_tokens: 77777` to its `params`. Start a new chat (no chat-control override). Observe `"max_tokens": 77777` — confirming the per-model path also works. The bug is specifically: per-chat override works, per-model `params` works, but the global `DEFAULT_MODEL_PARAMS` fallback for sampling params does NOT work on the OpenAI path. Same trace on the Ollama path. ### Logs & Screenshots Code trace against `main` at commit `d47c88f` (2026-05-20): **1. `backend/open_webui/main.py:1709-1713`** — the merge IS built with the correct precedence: ```python # Model params: global defaults as base, per-model overrides win default_model_params = getattr(request.app.state.config, 'DEFAULT_MODEL_PARAMS', None) or {} model_info_params = { **default_model_params, **(model_info.params.model_dump() if model_info and model_info.params else {}), } ``` **2. `backend/open_webui/main.py:1738-1791`** — but `model_info_params` is then ONLY consulted for four keys: `stream_response`, `stream_delta_chunk_size`, `reasoning_tags`, `function_calling`. Provider sampling params (`max_tokens`, `temperature`, `top_p`, etc.) are never read off the merged dict; the merged dict is dropped after this block. **3. `backend/open_webui/routers/openai.py:1115`** — the outbound payload builder reads `model_info.params` directly (NOT the merged dict from step 1): ```python params = model_info.params.model_dump() if params: system = params.pop('system', None) payload = apply_model_params_to_body_openai(params, payload) ``` So the global default fallback computed in `main.py` never reaches the OpenAI payload builder. **4. `backend/open_webui/routers/ollama.py`** — `params = model_info.params.model_dump()` appears at lines 1123, 1216, 1279 with the same shape. The Ollama path almost certainly has the same bug. (Not verified end-to-end against a live Ollama instance, but the source pattern is identical.) **5. `backend/open_webui/utils/payload.py::apply_model_params_to_body_openai`** confirms there's no internal fallback to a global default either — it just copies the provided dict's keys into form_data, falling back to Open WebUI's own hardcoded defaults (e.g. `max_tokens: 2048`) when a key is absent. Browser console logs and Docker container logs are not informative for this bug — it's a server-side payload-construction bug, evidenced entirely by inspecting the outbound request body sent to the upstream provider. ### Additional Information **Proposed fix**: change `routers/openai.py:1115` (and the three analogous sites in `routers/ollama.py`) to consume the merged `model_info_params` already computed in `main.py` rather than re-deriving from raw `model_info.params`. Either: - Plumb the merged dict through `payload['metadata']` (already used to pass other per-request context) and use it in the router; or - Move the merge into the router itself, by reading `request.app.state.config.DEFAULT_MODEL_PARAMS` before the call to `apply_model_params_to_body_openai` and merging it underneath the per-model dict; or - Have `apply_model_params_to_body_openai` accept a `default_params: dict | None` argument and apply it as a base layer before the per-model overrides. Whichever shape is preferred, the contract should be that **`DEFAULT_MODEL_PARAMS` is a true base layer for every provider sampling param**, not just the four Open WebUI-internal flags currently consulted in `main.py`. That matches what the admin UI implies and what users reasonably expect from a "Default Parameters" form. Happy to send a PR if a maintainer can confirm a preferred shape.
Author
Owner

@owui-terminator[bot] commented on GitHub (May 20, 2026):

🔍 Related Issues Found

I found some existing issues that might be related. Please check if any of these are duplicates or contain helpful solutions:

  1. 🟣 #19214 issue: default model params take precedence over user-specified model params
    This is closely related because it concerns the same DEFAULT_MODEL_PARAMS/admin default parameter path and the same precedence/merge logic around model parameters. The exact symptom differs, but it shows that default model params are involved in request construction and payload precedence bugs.
    by Simon-Stone · bug

  2. 🟣 #18618 issue: Root-level max_tokens dropped instead of converted to num_predict (Regression from Feb 2025)
    This issue is about max_tokens being dropped during backend payload conversion, which is very similar to the reported silent dropping of global default sampling params like max_tokens. It also covers the same general request-building path where token-limit parameters are lost before reaching the provider.
    by elazar · bug

  3. 🟣 #22524 issue: Newer OpenAI model max_tokens parameter bug
    This is another max_tokens-related OpenAI backend bug where the parameter is mishandled in outbound requests. While the root cause is different, it is relevant because it shows the OpenAI request path has recent regressions around token-limit parameter handling.
    by Art-1313 · bug

  4. 🟣 #22557 issue: User configured "Advanced Paramters" for Ollama models are sent to Open AI models
    This issue is about model parameters leaking across provider paths and being sent in the wrong outbound payload. It is not the same bug, but it is related to the same code area where Open WebUI builds and forwards request parameters to OpenAI-compatible providers.
    by derek-assurity · bug


💡 If your issue is a duplicate, please close it and add any additional details to the existing issue instead.

This comment was generated automatically. React with 👍 if helpful, 👎 if not.

<!-- gh-comment-id:4493895033 --> @owui-terminator[bot] commented on GitHub (May 20, 2026): <!-- terminator-bot:related-issues-reply --> 🔍 **Related Issues Found** I found some existing issues that might be related. Please check if any of these are duplicates or contain helpful solutions: 1. 🟣 [#19214](https://github.com/open-webui/open-webui/issues/19214) **issue: default model params take precedence over user-specified model params** *This is closely related because it concerns the same `DEFAULT_MODEL_PARAMS`/admin default parameter path and the same precedence/merge logic around model parameters. The exact symptom differs, but it shows that default model params are involved in request construction and payload precedence bugs.* *by Simon-Stone · `bug`* 2. 🟣 [#18618](https://github.com/open-webui/open-webui/issues/18618) **issue: Root-level max_tokens dropped instead of converted to num_predict (Regression from Feb 2025)** *This issue is about `max_tokens` being dropped during backend payload conversion, which is very similar to the reported silent dropping of global default sampling params like `max_tokens`. It also covers the same general request-building path where token-limit parameters are lost before reaching the provider.* *by elazar · `bug`* 3. 🟣 [#22524](https://github.com/open-webui/open-webui/issues/22524) **issue: Newer OpenAI model max_tokens parameter bug** *This is another `max_tokens`-related OpenAI backend bug where the parameter is mishandled in outbound requests. While the root cause is different, it is relevant because it shows the OpenAI request path has recent regressions around token-limit parameter handling.* *by Art-1313 · `bug`* 4. 🟣 [#22557](https://github.com/open-webui/open-webui/issues/22557) **issue: User configured "Advanced Paramters" for Ollama models are sent to Open AI models** *This issue is about model parameters leaking across provider paths and being sent in the wrong outbound payload. It is not the same bug, but it is related to the same code area where Open WebUI builds and forwards request parameters to OpenAI-compatible providers.* *by derek-assurity · `bug`* --- 💡 If your issue is a duplicate, please close it and add any additional details to the existing issue instead. *This comment was generated automatically.* React with 👍 if helpful, 👎 if not.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#123745