Skip to content

MemoryManager add_provider() leaves failed external provider half-registered #9948

@NewTurn2017

Description

@NewTurn2017

Bug Description

MemoryManager.add_provider() mutates internal state before provider.get_tool_schemas() succeeds. If get_tool_schemas() raises, the external provider remains in _providers and _has_external stays True, even though registration failed.

Affected files / lines

  • agent/memory_manager.py:94-129

Why this is a bug

The function sets _has_external = True and appends the provider before iterating provider.get_tool_schemas(). A failure during schema loading leaves the manager in a poisoned state for the rest of the process.

Minimal Reproduction

from agent.memory_manager import MemoryManager
from agent.memory_provider import MemoryProvider

class BrokenProvider(MemoryProvider):
    @property
    def name(self): return "broken"
    def is_available(self): return True
    def initialize(self, session_id: str, **kwargs): return None
    def get_tool_schemas(self): raise RuntimeError("boom")
    def call_tool(self, name, arguments): return {}
    def extract_memories(self, messages): return []
    def search(self, query, top_k=5): return []
    def add(self, content, metadata=None): return "id"
    def delete(self, memory_id): return True
    def list_tools(self): return []

class OkProvider(BrokenProvider):
    @property
    def name(self): return "ok"
    def get_tool_schemas(self): return []

mm = MemoryManager()
try:
    mm.add_provider(BrokenProvider())
except RuntimeError:
    pass

print([p.name for p in mm.providers], mm._has_external)
mm.add_provider(OkProvider())
print([p.name for p in mm.providers], mm._has_external)

Observed state after the failed add:

  • providers == ["broken"]
  • _has_external == True
  • a subsequent external provider is rejected with:
    • Rejected memory provider ok — external provider broken is already registered...

Expected Behavior

If provider registration fails, MemoryManager should roll back the partial registration so later providers can still be added.

Actual Behavior

A provider that never finished registering still blocks all future external providers in that process.

Suggested Investigation Direction

Load tool schemas before mutating manager state, or wrap the registration path in a rollback/transaction so _providers, _has_external, and _tool_to_provider stay consistent on failure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havecomp/pluginsPlugin system and bundled pluginstool/memoryMemory tool and memory providerstype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions