a3449c7 fix: UserValves contamination between multiple tools
📊 Changes
1 file changed (+6 additions, -3 deletions)
View changed files
📝backend/open_webui/utils/tools.py (+6 -3)
📄 Description
Description
Fixes a critical bug where multiple tools with UserValves would incorrectly share the same UserValves instance, causing tool-specific user configuration to leak between different tools.
Root Cause:functools.partial() was freezing a reference to the shared extra_params["__user__"] dict rather than creating isolated instances per tool.
Solution: Create a shallow copy of __user__ for each tool before setting its specific UserValves instance, ensuring partial() freezes the correct isolated configuration.
Testing
✅ Tested with 3 tools (DummyToolA, DummyToolB, DummyToolC) each with unique UserValves
✅ Verified each tool receives only its own UserValves configuration
✅ Confirmed no contamination between tools
✅ Manual testing with Anthropic Claude pipe and OpenAI models
Changelog Entry
Description
Fixed a critical bug where multiple tools with UserValves would share the same UserValves instance due to functools.partial() freezing a reference to the shared extra_params["user"] dict. This caused Tool B and Tool C to incorrectly receive Tool A's UserValves instead of their own configuration.
Added
N/A
Changed
Modified backend/open_webui/utils/tools.py to create a shallow copy of __user__ dict for each tool with UserValves before passing to functools.partial()
Deprecated
N/A
Removed
N/A
Fixed
Fixed UserValves contamination where multiple tools would share the same UserValves instance
Each tool now correctly receives its own isolated UserValves configuration
Security
N/A
Breaking Changes
N/A
Additional Information
Impact:
Performance: Minimal - one shallow dict copy per tool (not per function)
Breaking Changes: None - purely internal fix
Scope: Affects all tools using the UserValves feature
After: Creates tool_user = extra_params["__user__"].copy() and sets tool_user["valves"] before partial() freezes it
Screenshots or Videos
N/A - Backend fix with no UI changes
Contributor License Agreement
By submitting this pull request, I confirm that I have read and fully agree to the Contributor License Agreement (CLA), and I am providing my contributions under its terms.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/open-webui/open-webui/pull/19185
**Author:** [@Podden](https://github.com/Podden)
**Created:** 11/14/2025
**Status:** ❌ Closed
**Base:** `dev` ← **Head:** `bugfix/uservalves-contamination`
---
### 📝 Commits (1)
- [`a3449c7`](https://github.com/open-webui/open-webui/commit/a3449c7382c870c3bc5eb2d1bac4d13d09e8a649) fix: UserValves contamination between multiple tools
### 📊 Changes
**1 file changed** (+6 additions, -3 deletions)
<details>
<summary>View changed files</summary>
📝 `backend/open_webui/utils/tools.py` (+6 -3)
</details>
### 📄 Description
## Description
Fixes a critical bug where multiple tools with `UserValves` would incorrectly share the same `UserValves` instance, causing tool-specific user configuration to leak between different tools.
**Root Cause:** `functools.partial()` was freezing a reference to the shared `extra_params["__user__"]` dict rather than creating isolated instances per tool.
**Solution:** Create a shallow copy of `__user__` for each tool before setting its specific `UserValves` instance, ensuring `partial()` freezes the correct isolated configuration.
## Testing
- ✅ Tested with 3 tools (DummyToolA, DummyToolB, DummyToolC) each with unique UserValves
- ✅ Verified each tool receives only its own UserValves configuration
- ✅ Confirmed no contamination between tools
- ✅ Manual testing with Anthropic Claude pipe and OpenAI models
---
# Changelog Entry
### Description
Fixed a critical bug where multiple tools with UserValves would share the same UserValves instance due to functools.partial() freezing a reference to the shared extra_params["__user__"] dict. This caused Tool B and Tool C to incorrectly receive Tool A's UserValves instead of their own configuration.
### Added
- N/A
### Changed
- Modified `backend/open_webui/utils/tools.py` to create a shallow copy of `__user__` dict for each tool with UserValves before passing to `functools.partial()`
### Deprecated
- N/A
### Removed
- N/A
### Fixed
- Fixed UserValves contamination where multiple tools would share the same UserValves instance
- Each tool now correctly receives its own isolated UserValves configuration
### Security
- N/A
### Breaking Changes
- N/A
---
### Additional Information
**Impact:**
- Performance: Minimal - one shallow dict copy per tool (not per function)
- Breaking Changes: None - purely internal fix
- Scope: Affects all tools using the UserValves feature
**Technical Details:**
- Before: `extra_params["__user__"]["valves"] = module.UserValves(...)` directly modified shared dict
- After: Creates `tool_user = extra_params["__user__"].copy()` and sets `tool_user["valves"]` before partial() freezes it
### Screenshots or Videos
N/A - Backend fix with no UI changes
### Contributor License Agreement
By submitting this pull request, I confirm that I have read and fully agree to the [Contributor License Agreement (CLA)](https://github.com/open-webui/open-webui/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT), and I am providing my contributions under its terms.
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/open-webui/open-webui/pull/19185
Author: @Podden
Created: 11/14/2025
Status: ❌ Closed
Base:
dev← Head:bugfix/uservalves-contamination📝 Commits (1)
a3449c7fix: UserValves contamination between multiple tools📊 Changes
1 file changed (+6 additions, -3 deletions)
View changed files
📝
backend/open_webui/utils/tools.py(+6 -3)📄 Description
Description
Fixes a critical bug where multiple tools with
UserValveswould incorrectly share the sameUserValvesinstance, causing tool-specific user configuration to leak between different tools.Root Cause:
functools.partial()was freezing a reference to the sharedextra_params["__user__"]dict rather than creating isolated instances per tool.Solution: Create a shallow copy of
__user__for each tool before setting its specificUserValvesinstance, ensuringpartial()freezes the correct isolated configuration.Testing
Changelog Entry
Description
Fixed a critical bug where multiple tools with UserValves would share the same UserValves instance due to functools.partial() freezing a reference to the shared extra_params["user"] dict. This caused Tool B and Tool C to incorrectly receive Tool A's UserValves instead of their own configuration.
Added
Changed
backend/open_webui/utils/tools.pyto create a shallow copy of__user__dict for each tool with UserValves before passing tofunctools.partial()Deprecated
Removed
Fixed
Security
Breaking Changes
Additional Information
Impact:
Technical Details:
extra_params["__user__"]["valves"] = module.UserValves(...)directly modified shared dicttool_user = extra_params["__user__"].copy()and setstool_user["valves"]before partial() freezes itScreenshots or Videos
N/A - Backend fix with no UI changes
Contributor License Agreement
By submitting this pull request, I confirm that I have read and fully agree to the Contributor License Agreement (CLA), and I am providing my contributions under its terms.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.