mem0ai/mem0 · error · Mem0ValidationError

VALIDATION_001

VALIDATION_001

Error message

At least one of 'user_id', 'agent_id', or 'run_id' must be provided.

What it means

Raised as Mem0ValidationError (error code VALIDATION_001) by _build_filters_and_metadata when Memory.add() (and other scoped APIs) is called with none of user_id, agent_id, or run_id. Every memory in the OSS SDK must be scoped to at least one actor so that get_all/search/delete_all can filter by it; an unscoped write is always a programming error. The exception carries details showing exactly which IDs were provided (all None here) and a suggestion.

Source

Thrown at mem0/memory/main.py:392

    run_id = _validate_and_trim_entity_id(run_id, "run_id")

    if user_id:
        base_metadata_template["user_id"] = user_id
        effective_query_filters["user_id"] = user_id
        session_ids_provided.append("user_id")

    if agent_id:
        base_metadata_template["agent_id"] = agent_id
        effective_query_filters["agent_id"] = agent_id
        session_ids_provided.append("agent_id")

    if run_id:
        base_metadata_template["run_id"] = run_id
        effective_query_filters["run_id"] = run_id
        session_ids_provided.append("run_id")

    if not session_ids_provided:
        raise Mem0ValidationError(
            message="At least one of 'user_id', 'agent_id', or 'run_id' must be provided.",
            error_code="VALIDATION_001",
            details={"provided_ids": {"user_id": user_id, "agent_id": agent_id, "run_id": run_id}},
            suggestion="Please provide at least one identifier to scope the memory operation."
        )

    # ---------- optional actor filter ----------
    resolved_actor_id = actor_id or effective_query_filters.get("actor_id")
    if resolved_actor_id:
        effective_query_filters["actor_id"] = resolved_actor_id

    return base_metadata_template, effective_query_filters


def _escape_scope_value(val: Any) -> str:
    """Escape the structural delimiters of the session scope key."""
    return str(val).replace("%", "%25").replace("&", "%26").replace("=", "%3D")

View on GitHub (pinned to 001c235229)

Solutions

  1. Pass at least one keyword: m.add(messages, user_id='u1') (or agent_id='run' scope IDs).
  2. If the ID lives in metadata, move it to the keyword argument; metadata cannot substitute for the scoping parameters.
  3. Catch mem0.memory.utils.Mem0ValidationError in wrappers to return a clean 4xx to your own callers.
  4. Make your wrapper require the user_id parameter explicitly (mandatory argument) so it cannot be forgotten.

Example fix

# before
m.add("Prefers dark mode", metadata={"user_id": "alice"})

# after
m.add("Prefers dark mode", user_id="alice")
Defensive patterns

Strategy: validation

Validate before calling

if not any([user_id, agent_id, run_id]):
    raise ValueError("user_id, agent_id, or run_id is required to store a memory")

Type guard

def has_scope(user_id=None, agent_id=None, run_id=None) -> bool:
    return any(v for v in (user_id, agent_id, run_id))

Try / catch

from mem0.memory.utils import Mem0ValidationError
try:
    m.add(msg, user_id=uid)
except Mem0ValidationError as e:
    if e.error_code == "VALIDATION_001":
        return {"error": "missing user scope", "detail": str(e)}
    raise

Prevention

When it happens

Trigger: m.add("user prefers dark mode") with no user_id/agent_id/run_id keyword; IDs passed inside the metadata dict instead of as keyword arguments (metadata={'user_id': 'u1'} is ignored for scoping); a wrapper that forwards **kwargs but drops the ID arguments; user_id=None coming from an unset session variable.

Common situations: Integrating mem0 into a chat app where the user ID is in a session/context object that is not yet populated; porting code from the hosted MemoryClient API and assuming IDs are optional; passing identifiers in metadata and expecting them to act as filters.

Related errors


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/d4078c96fbc28f1c. Report an issue: GitHub.