agentscope-ai/agentscope · error · TypeError

"Mem0Middleware requires an async mem0 client (`mem0.AsyncMe

Error message

"Mem0Middleware requires an async mem0 client (`mem0.AsyncMemory` or `mem0.AsyncMemoryClient`). The synchronous `Memory` / `MemoryClient` are not supported."

What it means

Mem0Middleware only awaits client.search/add, so the client must be async. _looks_async inspects the callables and a synchronous mem0.Memory or MemoryClient fails the check with this explanatory TypeError.

Source

Thrown at src/agentscope/middleware/_longterm_memory/_mem0/_middleware.py:485

                    "`mem0_config` is not given.",
                )

            from mem0 import AsyncMemory

            from ._agentscope_adapter import build_mem0_config

            client = AsyncMemory(
                config=build_mem0_config(
                    chat_model=chat_model,
                    embedding_model=embedding_model,
                    mem0_config=mem0_config,
                ),
            )

        if not _looks_async(
            getattr(client, "search", None),
        ) or not _looks_async(getattr(client, "add", None)):
            raise TypeError(
                "Mem0Middleware requires an async mem0 client "
                "(`mem0.AsyncMemory` or `mem0.AsyncMemoryClient`). "
                "The synchronous `Memory` / `MemoryClient` are not "
                "supported.",
            )
        return client

    # ==================================================================
    # mem0 client adapters (OSS + Platform share this call shape)
    # ==================================================================
    async def _async_search(
        self,
        query: str,
        *,
        user_id: str,
        agent_id: str | None,
        top_k: int | None = None,
    ) -> list[str]:

View on GitHub (pinned to e90f1c7592)

Solutions

  1. Use mem0.AsyncMemory.from_config(...) or AsyncMemoryClient
  2. Keep the mem0_config/models path, which constructs AsyncMemory internally
  3. Verify with inspect.iscoroutinefunction(client.search) before passing

Example fix

// before
from mem0 import Memory
mw = Mem0Middleware(user_id='u1', client=Memory.from_config(cfg))
// after
from mem0 import AsyncMemory
mw = Mem0Middleware(user_id='u1', client=AsyncMemory.from_config(cfg))
Defensive patterns

Strategy: type-guard

Validate before calling

import inspect
assert inspect.iscoroutinefunction(getattr(client, 'search', None)), 'use AsyncMemory'
assert inspect.iscoroutinefunction(getattr(client, 'add', None)), 'use AsyncMemory'

Type guard

import inspect
def is_async_memory_client(c) -> bool:
    return inspect.iscoroutinefunction(getattr(c, 'search', None)) and inspect.iscoroutinefunction(getattr(c, 'add', None))

Try / catch

try:
    mw = Mem0Middleware(user_id='u1', client=client)
except TypeError as e:
    if 'async mem0 client' in str(e):
        from mem0 import AsyncMemory
        mw = Mem0Middleware(user_id='u1', client=AsyncMemory.from_config(cfg))
    else:
        raise

Prevention

When it happens

Trigger: Passing client=Memory.from_config(...) (sync) or MemoryClient(...) instead of AsyncMemory/AsyncMemoryClient.

Common situations: Copying sync mem0 quickstart code into an agentscope pipeline; mem0 version where the sync/async split moved classes.

Related errors


AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28). Data as JSON: /api/errors/3289d2f363f8a2d2. Report an issue: GitHub.