{"record":{"id":"2d0599f90ba871db","repo":"666ghj/MiroFish","slug":"zep-search-limit-must-be-an-integer","errorCode":null,"errorMessage":"Zep search limit must be an integer","messagePattern":"Zep search limit must be an integer","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/app/utils/zep.py","lineNumber":50,"sourceCode":"\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\n@lru_cache(maxsize=4)\ndef _cached_zep_client(api_key: str, timeout: float) -> Zep:\n    return Zep(\n        api_key=api_key,\n        base_url=ZEP_CLOUD_BASE_URL,\n        timeout=timeout,\n    )\n\n\ndef get_zep_client(api_key: str | None = None, timeout: float | None = None) -> Zep:\n    \"\"\"Return a process-shared, explicitly configured Zep Cloud client.\"\"\"\n\n    # zep-cloud gives ZEP_API_URL precedence even when base_url is explicit.","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/backend/app/utils/zep.py#L32-L68","documentation":"Raised by normalize_zep_search_limit in backend/app/utils/zep.py when int(limit) raises TypeError or ValueError — i.e. limit is None, a non-numeric string (\"\", \"ten\"), or a non-numeric type like dict/list. Numeric strings (\"10\") and floats (10.0) convert fine and do NOT trigger this. It is a ValueError chained from the original exception, raised before any Zep Cloud call.","triggerScenarios":"Passing limit=None (there is no None-default handling in this function), limit=\"\", or limit={\"size\": 10}. Forwarding unparsed HTTP query-string parameters (always str or None) directly as limit.","commonSituations":"A handler doing request.args.get(\"limit\") and forwarding it; a caller passing None expecting a library default to apply; config values arriving as empty strings when the field is unset.","solutions":["Resolve None/empty to an explicit default at the call site before calling: limit = int(raw) if raw else 10.","Parse query/config limits with a typed parser (Pydantic field, argparse type=int) at the boundary.","Pass an int literal when no configurability is needed."],"exampleFix":"# before\nresults = search(query=q, limit=request.args.get(\"limit\"))  # str or None\n\n# after\nraw = request.args.get(\"limit\")\nlimit = int(raw) if raw else 10\nresults = search(query=q, limit=limit)","handlingStrategy":"validation","validationCode":"def coerce_limit(raw: Any, default: int = 10) -> int:\n    if raw is None or raw == \"\":\n        return default\n    return int(raw)  # surface bad input early at the boundary","typeGuard":"def is_int_like_limit(value: Any) -> TypeGuard[int]:\n    if isinstance(value, bool):\n        return False\n    try:\n        int(value)\n        return True\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    limit = normalize_zep_search_limit(raw_limit)\nexcept ValueError:\n    limit = 10  # sane default for untrusted input","preventionTips":["Parse query-string/config limits with typed parsers (Pydantic, type=int) before they reach the Zep layer.","Never forward None for limit; resolve None to an explicit default yourself.","Beware bools: int(True) == 1 passes conversion — reject bool explicitly if it can reach this path."],"tags":["validation","zep","type-coercion","pagination"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}