{"record":{"id":"1304013314d25c62","repo":"mem0ai/mem0","slug":"invalid-threshold-threshold-must-be-between-0-130401","errorCode":null,"errorMessage":"Invalid threshold: {threshold}. Must be between 0 and 1 (inclusive).","messagePattern":"Invalid threshold: (.+?)\\. Must be between 0 and 1 \\(inclusive\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/memory/main.py","lineNumber":227,"sourceCode":"    return trimmed\n\n\ndef _validate_search_params(threshold: Optional[float] = None, top_k: Optional[int] = None) -> None:\n    \"\"\"\n    Validates search parameters.\n\n    Args:\n        threshold: Similarity threshold (must be between 0 and 1)\n        top_k: Number of results to return (must be non-negative integer)\n\n    Raises:\n        ValueError: If threshold or top_k are invalid\n    \"\"\"\n    if threshold is not None:\n        if not isinstance(threshold, (int, float)):\n            raise ValueError(\"threshold must be a valid number\")\n        if threshold < 0 or threshold > 1:\n            raise ValueError(\n                f\"Invalid threshold: {threshold}. Must be between 0 and 1 (inclusive).\"\n            )\n    if top_k is not None:\n        if not isinstance(top_k, int) or isinstance(top_k, bool):\n            raise ValueError(\"top_k must be a valid integer\")\n        if top_k < 0:\n            raise ValueError(\n                f\"Invalid top_k: {top_k}. Must be a non-negative integer.\"\n            )\n\n\ndef _validate_and_trim_search_query(query: str) -> str:\n    \"\"\"\n    Validates and normalizes a search query before embedding/vector search.\n\n    Raises:\n        ValueError: If query is not a string or is empty/whitespace-only.\n    \"\"\"","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/memory/main.py#L209-L245","documentation":"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.","triggerScenarios":"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).","commonSituations":"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).","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."],"exampleFix":"# before\nresults = m.search(\"python tips\", filters={\"user_id\": \"u1\"}, threshold=75)\n\n# after\nresults = m.search(\"python tips\", filters={\"user_id\": \"u1\"}, threshold=0.75)","handlingStrategy":"validation","validationCode":"def validate_threshold(t):\n    if t is None:\n        return None\n    if not isinstance(t, (int, float)) or isinstance(t, bool):\n        raise ValueError(\"threshold must be a number\")\n    if not 0.0 <= t <= 1.0:\n        raise ValueError(f\"threshold {t} out of range [0,1]; did you mean {t/100}?\")\n    return float(t)\n\nthreshold = validate_threshold(cfg.get(\"threshold\"))\nresults = m.search(q, filters=f, threshold=threshold)","typeGuard":"def is_valid_threshold(t) -> bool:\n    return t is None or (isinstance(t, (int, float)) and not isinstance(t, bool) and 0.0 <= t <= 1.0)","tryCatchPattern":null,"preventionTips":["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."],"tags":["validation","search","threshold","valueerror"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}