{"record":{"id":"13e4e9b5f6f227e2","repo":"666ghj/MiroFish","slug":"zep-search-query-must-be-a-string","errorCode":null,"errorMessage":"Zep search query must be a string","messagePattern":"Zep search query must be a string","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/app/utils/zep.py","lineNumber":37,"sourceCode":"T = TypeVar(\"T\")\n\nZEP_CLOUD_BASE_URL = \"https://api.getzep.com/api/v2\"\n# Keep request behavior aligned with the zep-cloud 3.25.0 SDK default that\n# MiroFish used before introducing the shared client. This is an internal\n# integration policy, not a deployment setting users need to tune.\nZEP_HTTP_REQUEST_TIMEOUT_SECONDS = 60.0\n# Zep ingestion is asynchronous and may take several minutes. Preserve the\n# original GraphBuilder deadline while keeping it separate from HTTP timeout.\nZEP_INGESTION_WAIT_TIMEOUT_SECONDS = 600\nMAX_ZEP_SEARCH_QUERY_CHARS = 400\nMAX_ZEP_SEARCH_RESULTS = 50\n\n\ndef normalize_zep_search_query(query: Any) -> str:\n    \"\"\"Return a non-empty query within Zep Cloud's endpoint limit.\"\"\"\n\n    if not isinstance(query, str):\n        raise ValueError(\"Zep search query must be a string\")\n    normalized = query.strip()\n    if not normalized:\n        raise ValueError(\"Zep search query must not be empty\")\n    return normalized[:MAX_ZEP_SEARCH_QUERY_CHARS]\n\n\ndef normalize_zep_search_limit(limit: Any) -> int:\n    \"\"\"Clamp a search result limit to the current Zep Cloud contract.\"\"\"\n\n    try:\n        normalized = int(limit)\n    except (TypeError, ValueError) as exc:\n        raise ValueError(\"Zep search limit must be an integer\") from exc\n    if normalized < 1:\n        raise ValueError(\"Zep search limit must be at least 1\")\n    return min(normalized, MAX_ZEP_SEARCH_RESULTS)\n\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/backend/app/utils/zep.py#L19-L55","documentation":"ValueError raised by normalize_zep_search_query when the query argument is not a str instance (None, int, list, dict, bytes). It is a type gate in front of Zep Cloud's search endpoint, which expects a non-empty string capped at MAX_ZEP_SEARCH_QUERY_CHARS (400).","triggerScenarios":"Passing a non-string into a Zep search helper: None from an unset variable, a dict/list from upstream JSON, or a number coerced nowhere. The check runs before any network call, so it fails locally and immediately.","commonSituations":"LLM-generated tool-call arguments (a model emitting null or a nested object for the query parameter), unvalidated API request bodies, or default parameter values like None not replaced before the call.","solutions":["Coerce or validate the query to a non-empty string before calling the search helper: str(query).strip() if it is scalar, else reject","At the API/tool boundary, validate request parameters against a schema (e.g. pydantic) so None never reaches here","For LLM tool calls, re-ask the model or substitute a clear error message when the argument is the wrong type"],"exampleFix":"# before\nresults = zep_search(query=params.get(\"query\"))  # None -> ValueError\n\n# after\nraw = params.get(\"query\")\nif not isinstance(raw, str) or not raw.strip():\n    raise ValueError(\"'query' must be a non-empty string\")\nresults = zep_search(query=raw)","handlingStrategy":"type-guard","validationCode":"if not isinstance(query, str) or not query.strip():\n    raise ValueError(\"'query' must be a non-empty string\")","typeGuard":"def is_valid_zep_query(q: Any) -> bool:\n    return isinstance(q, str) and bool(q.strip())","tryCatchPattern":"try:\n    results = zep_search(query=q)\nexcept ValueError as e:\n    if \"must be a string\" in str(e):\n        q = str(q).strip() if q else None\n        if not q:\n            raise\n        results = zep_search(query=q)","preventionTips":["Validate tool-call/API parameters with a schema (pydantic) at the boundary","For LLM tool calls, define the query parameter as type string with minLength 1","Coerce scalars to str early; reject None and containers outright"],"tags":["zep","validation","type-guard","search"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}