[GH-ISSUE #22913] issue: Chat input loses skill and @ model selection state on page refresh #35370

Closed
opened 2026-04-25 09:35:19 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @silentoplayz on GitHub (Mar 21, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/22913

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.

Installation Method

Docker

Open WebUI Version

v0.8.10

Ollama Version (if applicable)

v0.18.0

Operating System

Ubuntu 24.04.4 LTS

Browser (if applicable)

Mozilla Firefox Snap for Ubuntu v148.0.2 (64-bit) / Google Chrome v146.0.7680.80 (Official Build) (64-bit)

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. My steps:
  • Start with the initial platform/version/OS and dependencies used,
  • Specify exact install/launch/configure commands,
  • List URLs visited, user input (incl. example values/emails/passwords if needed),
  • Describe all options and toggles enabled or changed,
  • Include any files or environmental changes,
  • Identify the expected and actual result at each stage,
  • Ensure any reasonably skilled user can follow and hit the same issue.

Expected Behavior

When typing in the chat input with a skill selected (via the $ trigger) or a model selected via the @ mention trigger, refreshing the page should preserve these UI selection states alongside the existing text input draft restoration. Specifically:

  1. Skills: After typing $ to trigger the skill suggestion dropdown and selecting a skill, refreshing the page should retain the active skill selection and its visual highlighting in the input area.
  2. @ Model Selection: After typing @ to trigger the model suggestion dropdown and selecting a specific model, refreshing the page should retain the selected model's highlighted/active state in the input.

Currently, the text content (prompt) is correctly restored from sessionStorage on page reload, but the skill and @ model selection states are silently discarded.

Actual Behavior

After selecting a skill via $ or a model via @, if the page is refreshed:

  1. Skills: The $ text remains in the input (as plain text), but the skill selection state is lost. The skill's active/highlighted state disappears, and the skill suggestion dropdown is no longer active.
  2. @ Model Selection: The @ text remains in the input (as plain text), but the selected model state (atSelectedModel) is cleared. The model suggestion dropdown's active selection is lost.

Both states appear to be transient — they exist in Svelte component memory but are never written to sessionStorage or localStorage, so they are not restored on page reload.

Steps to Reproduce

  1. Start an Open WebUI instance on Ubuntu 24.04.4 LTS using Docker.
  2. Open a browser (Firefox v148.0.2 or Chrome v146.0.7680.80) and navigate to the Open WebUI chat interface.
  3. Test Skill State:
    a. In the chat input, type $ to trigger the skill suggestion dropdown.
    b. Select a skill from the dropdown.
    c. Observe the skill is active/highlighted in the input area.
    d. Press F5 or refresh the page.
    e. Observe the $skillname text remains in the input, but the skill's active/highlighted state is gone.
  4. Test @ Model Selection:
    a. In the chat input, type @ to trigger the model suggestion dropdown.
    b. Select a model from the dropdown.
    c. Observe the model is selected and the input shows @model-name.
    d. Press F5 or refresh the page.
    e. Observe the model's selected/active state is cleared.
  5. Verify Other State IS Restored:
    a. Type some regular text in the chat input.
    b. Refresh the page.
    c. Confirm the typed text IS restored (existing draft restoration works).

Logs & Screenshots

Before page refresh (skill selected): Screenshot shows skill $some-skill highlighted/active in the input.

Image

After page refresh (skill state lost): Screenshot shows $some-skill text still present but skill highlight/suggestion dropdown state lost.

Image

Before page refresh (@ model selected): Screenshot shows the model highlighted.

Image

After page refresh (@ model state lost): Screenshot shows the model suggestion dropdown's active selection cleared.

Image

No console errors are produced — this is a silent state loss, not a crash.

Additional Information

Root Cause Analysis

The chat input draft is persisted to sessionStorage via the saveDraft() function in src/lib/components/chat/Chat.svelte (lines 2581-2596). The draft object is assembled in src/lib/components/chat/MessageInput.svelte via the onChange reactive statement (lines 157-173):

$: onChange({
    prompt,
    files: files.filter((file) => file.type !== 'image').map(...),
    selectedToolIds,
    selectedFilterIds,
    imageGenerationEnabled,
    webSearchEnabled,
    codeInterpreterEnabled
    // NOTE: atSelectedModel and command (skill) are NOT included
});

The following state is NOT included in the draft and therefore not persisted across page reloads:

Feature State Variable Persisted?
Text input content prompt Yes (via draft)
Attached files files Yes (via draft)
Tool/filter toggles selectedToolIds, selectedFilterIds Yes (via draft)
Tool/filter toggles selectedToolIds, selectedFilterIds ⚠️ Unclear — included in draft onChange payload and draft restore block, but may be overridden by model-default tools before restore fires
Feature toggles webSearchEnabled, imageGenerationEnabled, codeInterpreterEnabled ⚠️ Unclear — included in draft but not independently verified
@ model selection atSelectedModel No
$ skill active state command (transient skill tracking) No

Relevant Files

  • src/lib/components/chat/MessageInput.svelte — The onChange reactive handler (lines 157-173) needs to include atSelectedModel and command in the draft object.
  • src/lib/components/chat/Chat.svelte — The draft restoration logic (around lines 225-250) needs to restore atSelectedModel and command alongside the existing fields.

Additional Bug: Tool/Filter Toggles May Also Not Persist

Upon further investigation, selectedToolIds, selectedFilterIds, webSearchEnabled, imageGenerationEnabled, and codeInterpreterEnabled are included in the onChange draft object (MessageInput.svelte lines 168-172) and appear in the draft restore block (Chat.svelte lines 240-244). However, in the init() function, selectedToolIds is first set by the model-auto-selection reactive statement (from model?.info?.meta?.toolIds) before the draft restore block runs, which could cause model-default tools to override any restored draft tools. This requires further investigation and manual testing to confirm whether tool/filter toggles reliably persist across page reloads.

Suggested Fix

  1. In MessageInput.svelte: Add atSelectedModel and command to the onChange draft object so they are saved to sessionStorage.
  2. In Chat.svelte: Extract atSelectedModel and command from the parsed draft JSON and restore them via the messageInput component's prop bindings (similar to how prompt, files, selectedToolIds, etc. are already restored).
  3. For tool/filter toggles: Investigate whether the model-default tools override (init() reactive statement firing before draft restore) is causing tool state to be lost, and add atSelectedModel to the draft and restore blocks as well.
Originally created by @silentoplayz on GitHub (Mar 21, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/22913 ### 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. ### Installation Method Docker ### Open WebUI Version v0.8.10 ### Ollama Version (if applicable) v0.18.0 ### Operating System Ubuntu 24.04.4 LTS ### Browser (if applicable) Mozilla Firefox Snap for Ubuntu v148.0.2 (64-bit) / Google Chrome v146.0.7680.80 (Official Build) (64-bit) ### 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**. My steps: - Start with the initial platform/version/OS and dependencies used, - Specify exact install/launch/configure commands, - List URLs visited, user input (incl. example values/emails/passwords if needed), - Describe all options and toggles enabled or changed, - Include any files or environmental changes, - Identify the expected and actual result at each stage, - Ensure any reasonably skilled user can follow and hit the same issue. ### Expected Behavior When typing in the chat input with a skill selected (via the `$` trigger) or a model selected via the `@` mention trigger, refreshing the page should preserve these UI selection states alongside the existing text input draft restoration. Specifically: 1. **Skills**: After typing `$` to trigger the skill suggestion dropdown and selecting a skill, refreshing the page should retain the active skill selection and its visual highlighting in the input area. 2. **`@` Model Selection**: After typing `@` to trigger the model suggestion dropdown and selecting a specific model, refreshing the page should retain the selected model's highlighted/active state in the input. Currently, the text content (`prompt`) is correctly restored from `sessionStorage` on page reload, but the skill and `@` model selection states are silently discarded. ### Actual Behavior After selecting a skill via `$` or a model via `@`, if the page is refreshed: 1. **Skills**: The `$` text remains in the input (as plain text), but the skill selection state is lost. The skill's active/highlighted state disappears, and the skill suggestion dropdown is no longer active. 2. **`@` Model Selection**: The `@` text remains in the input (as plain text), but the selected model state (`atSelectedModel`) is cleared. The model suggestion dropdown's active selection is lost. Both states appear to be transient — they exist in Svelte component memory but are never written to `sessionStorage` or `localStorage`, so they are not restored on page reload. ### Steps to Reproduce 1. Start an Open WebUI instance on Ubuntu 24.04.4 LTS using Docker. 2. Open a browser (Firefox v148.0.2 or Chrome v146.0.7680.80) and navigate to the Open WebUI chat interface. 3. **Test Skill State**: a. In the chat input, type `$` to trigger the skill suggestion dropdown. b. Select a skill from the dropdown. c. Observe the skill is active/highlighted in the input area. d. Press F5 or refresh the page. e. Observe the `$skillname` text remains in the input, but the skill's active/highlighted state is gone. 4. **Test `@` Model Selection**: a. In the chat input, type `@` to trigger the model suggestion dropdown. b. Select a model from the dropdown. c. Observe the model is selected and the input shows `@model-name`. d. Press F5 or refresh the page. e. Observe the model's selected/active state is cleared. 5. **Verify Other State IS Restored**: a. Type some regular text in the chat input. b. Refresh the page. c. Confirm the typed text IS restored (existing draft restoration works). ### Logs & Screenshots **Before page refresh (skill selected):** Screenshot shows skill `$some-skill` highlighted/active in the input. <img width="2342" height="130" alt="Image" src="https://github.com/user-attachments/assets/e2518229-e559-4658-90b4-e0da8b58c74e" /> **After page refresh (skill state lost):** Screenshot shows `$some-skill` text still present but skill highlight/suggestion dropdown state lost. <img width="2342" height="130" alt="Image" src="https://github.com/user-attachments/assets/ffe2d453-8671-4d7e-b330-92665b9cac54" /> **Before page refresh (`@` model selected):** Screenshot shows the model highlighted. <img width="2345" height="156" alt="Image" src="https://github.com/user-attachments/assets/12c8a6c6-0f8f-419b-9bc4-14add69de718" /> **After page refresh (`@` model state lost):** Screenshot shows the model suggestion dropdown's active selection cleared. <img width="2345" height="156" alt="Image" src="https://github.com/user-attachments/assets/14eac856-5760-4ca0-b651-6a418375309a" /> No console errors are produced — this is a silent state loss, not a crash. ### Additional Information ### Root Cause Analysis The chat input draft is persisted to `sessionStorage` via the `saveDraft()` function in `src/lib/components/chat/Chat.svelte` (lines 2581-2596). The draft object is assembled in `src/lib/components/chat/MessageInput.svelte` via the `onChange` reactive statement (lines 157-173): ```javascript $: onChange({ prompt, files: files.filter((file) => file.type !== 'image').map(...), selectedToolIds, selectedFilterIds, imageGenerationEnabled, webSearchEnabled, codeInterpreterEnabled // NOTE: atSelectedModel and command (skill) are NOT included }); ``` The following state is **NOT** included in the draft and therefore not persisted across page reloads: | Feature | State Variable | Persisted? | |---------|---------------|------------| | Text input content | `prompt` | ✅ Yes (via draft) | | Attached files | `files` | ✅ Yes (via draft) | | Tool/filter toggles | `selectedToolIds`, `selectedFilterIds` | ✅ Yes (via draft) | | Tool/filter toggles | `selectedToolIds`, `selectedFilterIds` | ⚠️ Unclear — included in draft `onChange` payload and draft restore block, but may be overridden by model-default tools before restore fires | | Feature toggles | `webSearchEnabled`, `imageGenerationEnabled`, `codeInterpreterEnabled` | ⚠️ Unclear — included in draft but not independently verified | | **`@` model selection** | `atSelectedModel` | ❌ No | | **`$` skill active state** | `command` (transient skill tracking) | ❌ No | ### Relevant Files - `src/lib/components/chat/MessageInput.svelte` — The `onChange` reactive handler (lines 157-173) needs to include `atSelectedModel` and `command` in the draft object. - `src/lib/components/chat/Chat.svelte` — The draft restoration logic (around lines 225-250) needs to restore `atSelectedModel` and `command` alongside the existing fields. ### Additional Bug: Tool/Filter Toggles May Also Not Persist Upon further investigation, `selectedToolIds`, `selectedFilterIds`, `webSearchEnabled`, `imageGenerationEnabled`, and `codeInterpreterEnabled` are included in the `onChange` draft object (MessageInput.svelte lines 168-172) and appear in the draft restore block (Chat.svelte lines 240-244). However, in the `init()` function, `selectedToolIds` is first set by the model-auto-selection reactive statement (from `model?.info?.meta?.toolIds`) before the draft restore block runs, which could cause model-default tools to override any restored draft tools. This requires further investigation and manual testing to confirm whether tool/filter toggles reliably persist across page reloads. ### Suggested Fix 1. **In `MessageInput.svelte`**: Add `atSelectedModel` and `command` to the `onChange` draft object so they are saved to `sessionStorage`. 2. **In `Chat.svelte`**: Extract `atSelectedModel` and `command` from the parsed draft JSON and restore them via the `messageInput` component's prop bindings (similar to how `prompt`, `files`, `selectedToolIds`, etc. are already restored). 3. **For tool/filter toggles**: Investigate whether the model-default tools override (`init()` reactive statement firing before draft restore) is causing tool state to be lost, and add `atSelectedModel` to the draft and restore blocks as well.
GiteaMirror added the bugconfirmed issue labels 2026-04-25 09:35:19 -05:00
Author
Owner

@tjbck commented on GitHub (Mar 24, 2026):

atSelectedModel is intended to be ephemeral. $skills rendering issue fixed.

<!-- gh-comment-id:4121810177 --> @tjbck commented on GitHub (Mar 24, 2026): `atSelectedModel` is intended to be ephemeral. $skills rendering issue fixed.
Author
Owner

@silentoplayz commented on GitHub (Mar 24, 2026):

atSelectedModel is intended to be ephemeral. $skills rendering issue fixed.

$skills also appears to be ephemeral now (disappears from the message input field on a page refresh). Is this intended?

<!-- gh-comment-id:4122086888 --> @silentoplayz commented on GitHub (Mar 24, 2026): > `atSelectedModel` is intended to be ephemeral. $skills rendering issue fixed. $skills also appears to be ephemeral now (disappears from the message input field on a page refresh). Is this intended?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#35370