mem0ai/mem0 · error · ValueError

Invalid top_k: {top_k}. Must be a non-negative integer.

Error message

Invalid top_k: {top_k}. Must be a non-negative integer.

What it means

Raised by _validate_search_params when top_k is an int but negative (top_k < 0). Requesting a negative number of results is meaningless, so the SDK rejects it with a ValueError before touching the vector store. Zero is allowed and simply returns no results.

Source

Thrown at mem0/memory/main.py:234

    Args:
        threshold: Similarity threshold (must be between 0 and 1)
        top_k: Number of results to return (must be non-negative integer)

    Raises:
        ValueError: If threshold or top_k are invalid
    """
    if threshold is not None:
        if not isinstance(threshold, (int, float)):
            raise ValueError("threshold must be a valid number")
        if threshold < 0 or threshold > 1:
            raise ValueError(
                f"Invalid threshold: {threshold}. Must be between 0 and 1 (inclusive)."
            )
    if top_k is not None:
        if not isinstance(top_k, int) or isinstance(top_k, bool):
            raise ValueError("top_k must be a valid integer")
        if top_k < 0:
            raise ValueError(
                f"Invalid top_k: {top_k}. Must be a non-negative integer."
            )


def _validate_and_trim_search_query(query: str) -> str:
    """
    Validates and normalizes a search query before embedding/vector search.

    Raises:
        ValueError: If query is not a string or is empty/whitespace-only.
    """
    if not isinstance(query, str):
        raise ValueError("Invalid query: must be a non-empty string.")
    trimmed = query.strip()
    if not trimmed:
        raise ValueError("Invalid query: cannot be empty or whitespace-only.")
    return trimmed

View on GitHub (pinned to 001c235229)

Solutions

  1. Clamp the value: top_k = max(0, top_k).
  2. Fix the pagination arithmetic that produced a negative count.
  3. Use a large positive number (e.g. 100) or the SDK default instead of -1 to mean 'many results'.
  4. Add an assert or pre-check in your own wrapper before calling mem0.

Example fix

# before
top_k = limit - offset  # can go negative
m.search(q, filters=f, top_k=top_k)

# after
top_k = max(0, limit - offset)
if top_k == 0:
    return []
m.search(q, filters=f, top_k=top_k)
Defensive patterns

Strategy: validation

Validate before calling

top_k = max(0, int(top_k))
if top_k == 0:
    return []  # nothing to fetch

Type guard

def is_valid_top_k(k) -> bool:
    return k is None or (isinstance(k, int) and not isinstance(k, bool) and k >= 0)

Prevention

When it happens

Trigger: m.search(query, filters={'user_id':'u1'}, top_k=-1); top_k computed as a subtraction that underflows (e.g. top_k = limit - offset where offset > limit); a loop decrementing top_k below zero; parsing a negative number from user input without clamping.

Common situations: Pagination arithmetic bugs (limit - page*size going negative on the last page); passing -1 as an 'all results' sentinel that worked in another API but is invalid here; sign errors in config.

Related errors


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