🐛 Bugfix: Guard memory_user_config against None in store/search memory tools#3359
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a crash in the SDK’s active memory tools by guarding accesses to memory_user_config when it is None, and defaulting to a privacy-preserving “no agent-level sharing” behavior.
Changes:
- Add
Noneguards formemory_user_configinStoreMemoryToolto preventAttributeErrorand default to removing the"agent"memory level. - Add the same
Noneguards inSearchMemoryTool, defaulting to searching without the"agent"memory level.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| sdk/nexent/core/tools/store_memory_tool.py | Avoids NoneType crashes by defaulting to no agent-level memory storage when user config is unavailable. |
| sdk/nexent/core/tools/search_memory_tool.py | Avoids NoneType crashes by defaulting to no agent-level memory search when user config is unavailable. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
68a00ab to
90b9661
Compare
…y tools Add None checks before accessing memory_user_config attributes in StoreMemoryTool and SearchMemoryTool. When config is unavailable, apply conservative default (agent_share_option='never') to prevent unintended cross-agent memory sharing.
90b9661 to
06fa9ab
Compare
- Fix nested array syntax bug that hid Tenant Shared and Agent Shared tabs - Conditionally hide Tenant Shared tab when isSpeedMode=true (no tenant concept) - All 5 tabs now properly visible in non-speed mode - 4 tabs visible in speed mode (Tenant Shared hidden)
…em tool filtering - test_store_memory_tool: add None config, _run_coroutine tests - test_search_memory_tool: add None config, _run_coroutine tests - test_memory_config_service: add duplicate record cleanup tests - test_tool_configuration_service: add SYSTEM_MANAGED_TOOL_NAMES filter test
WMC001
approved these changes
Jul 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
This PR addresses multiple memory-related issues discovered during development and testing:
1. NoneType crash in memory tools
StoreMemoryToolandSearchMemoryToolcrash withAttributeError: 'NoneType' object has no attribute 'agent_share_option'whenmemory_user_configisNone.This occurs in two scenarios:
POST /api/tool/validate):_validate_local_toolinstantiatesStoreMemoryToolvia the genericelsebranch with defaultmemory_user_config=Nonememory_user_configcan beNonewhen metadata is not properly propagated to the tool instance2. Duplicate tool names at runtime
store_memoryandsearch_memoryare system-managed tools that should be auto-injected when memory is enabled. They should not appear in the agent tool selection UI or be manually selectable by users. When present in both DB config and auto-injection,smolagentsrejects with "Each tool or managed_agent should have a unique name".3. Memory switch not persisting
The memory switch toggle in the UI would not persist after being enabled, because duplicate records in
memory_user_config_tcaused the aggregation logic to overwrite the latest value with stale data.4. Hidden memory tabs in configuration page
The Tenant Shared and Agent Shared tabs in the memory configuration page were hidden due to a nested array syntax bug in
tabItems. Additionally, the Tenant Shared tab should not be visible in speed mode (no tenant concept).Fix
1. None guard for memory_user_config
Add
Nonechecks before accessingmemory_user_configattributes in both tools. When config is unavailable, apply a conservative default equivalent toagent_share_option="never"— disabling agent-level memory sharing to protect user privacy.Files changed:
sdk/nexent/core/tools/store_memory_tool.pysdk/nexent/core/tools/search_memory_tool.pyBehavior when
memory_user_configisNone:user_agentlevel (removesagentlevel)["tenant", "user", "user_agent"](removesagentlevel)2. System-managed tools hidden from UI
store_memoryandsearch_memoryare system-managed tools — they should not appear in the agent tool selection UI.Files changed:
backend/consts/tool_labels.py— AddedSYSTEM_MANAGED_TOOL_NAMESconstantbackend/services/tool_configuration_service.py— Filter system-managed tools fromlist_all_toolsresponsebackend/agents/create_agent_info.py— Remove any existing memory tools from DB config before injecting the active memory versions (safety net for legacy data)Three-layer protection:
list_all_toolsdoes not returnstore_memory/search_memory, preventing users from manually selecting themcreate_agent_info.pyremoves any DB-configured memory tools before appending the platform-injected versions3. Memory switch persistence fix
Clean up duplicate records in
memory_user_config_twhen updating single-type config entries. The_update_single_configfunction now detects and removes stale duplicates after updating the primary record.File changed:
backend/services/memory_config_service.pyRoot cause: Multiple records existed for the same
(user_id, config_key)pair with different values. The_aggregate_recordsfunction processes records in insertion order, so a stale'N'record inserted after the latest'Y'record would overwrite the correct value.4. Memory configuration page tab fix
Fix nested array syntax bug that hid Tenant Shared and Agent Shared tabs. Conditionally hide Tenant Shared tab in speed mode.
File changed:
frontend/app/[locale]/memory/page.tsxChanges:
[...]nested array → proper spread with...(!isSpeedMode ? [...] : [])for Tenant SharedtabItemsTesting
store_memory(content=...)in an actual conversation withoutAttributeError"Memory stored successfully."with noNoneTypeerrorsstore_memory/search_memoryoptionsstore_memoryDB config runs without "duplicate name" errors