mem0ai/mem0 · error · ValueError
Invalid threshold: {threshold}. Must be between 0 and 1 (inc
Error message
Invalid threshold: {threshold}. Must be between 0 and 1 (inclusive). What it means
Raised by the private helper _validate_search_params in the OSS Memory SDK when the 'threshold' argument passed to Memory.search() (or any API that forwards to it) is a number outside the inclusive range [0, 1]. The threshold controls the minimum similarity score for returned memories, so values below 0 or above 1 are meaningless for cosine-similarity scoring and are rejected before any embedding or vector-store call is made. It is a plain ValueError raised during argument validation, so no network or LLM cost is incurred.
Source
Thrown at mem0/memory/main.py:227
return trimmed
def _validate_search_params(threshold: Optional[float] = None, top_k: Optional[int] = None) -> None:
"""
Validates search parameters.
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.
"""View on GitHub (pinned to 001c235229)
Solutions
- Change the threshold to a float between 0 and 1 inclusive (e.g. 0.75 instead of 75, or 0.4 instead of a distance like 1.5).
- If you intended a percentage, divide by 100 before passing it.
- If you actually wanted a distance-based cutoff, remember mem0 OSS uses similarity scores; lower threshold = more results, and pass None to use the default.
- Leave threshold=None to accept the SDK default instead of guessing a value.
Example fix
# before
results = m.search("python tips", filters={"user_id": "u1"}, threshold=75)
# after
results = m.search("python tips", filters={"user_id": "u1"}, threshold=0.75) Defensive patterns
Strategy: validation
Validate before calling
def validate_threshold(t):
if t is None:
return None
if not isinstance(t, (int, float)) or isinstance(t, bool):
raise ValueError("threshold must be a number")
if not 0.0 <= t <= 1.0:
raise ValueError(f"threshold {t} out of range [0,1]; did you mean {t/100}?")
return float(t)
threshold = validate_threshold(cfg.get("threshold"))
results = m.search(q, filters=f, threshold=threshold) Type guard
def is_valid_threshold(t) -> bool:
return t is None or (isinstance(t, (int, float)) and not isinstance(t, bool) and 0.0 <= t <= 1.0) Prevention
- Normalize percentage-style thresholds (0-100) to fractions by dividing by 100 at your config boundary.
- Centralize threshold handling in one wrapper so the range check happens once, with a helpful message.
- Write a unit test asserting 0 and 1 are accepted and -0.01/1.01 are rejected.
When it happens
Trigger: Calling m.search(query='...', filters={'user_id':'u1'}, threshold=1.2), threshold=-0.01, or threshold=5. Also triggered when threshold is computed dynamically (e.g. a percentage like 75 instead of 0.75) or read from config/env as a percentage. Note booleans are accepted here because bool is a subclass of int and only the range check applies (True==1 passes, False==0 passes).
Common situations: Developers porting code from another vector DB API where thresholds are 0-100 percentages; mixing up 'top_k' and 'threshold' argument order; copying a score threshold from a different similarity metric (e.g. a distance threshold like 1.5 for L2 distance, which is valid in Qdrant/Pinecone but not here).
Related errors
- threshold must be a valid number
- Invalid threshold: ${threshold}. Must be between 0 and 1 (in
- topK must be a valid integer
- Invalid topK: ${topK}. Must be a non-negative integer.
- filters must contain at least one of: user_id, agent_id, run
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/1304013314d25c62.
Report an issue: GitHub.