{"record":{"id":"b8a2637eaeba5048","repo":"666ghj/MiroFish","slug":"zep-request-timeout-must-be-greater-than-0","errorCode":null,"errorMessage":"Zep request timeout must be greater than 0","messagePattern":"Zep request timeout must be greater than 0","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/app/utils/zep.py","lineNumber":82,"sourceCode":"\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.\n    # Reject it so this Cloud-only integration cannot silently target a\n    # self-hosted or compatibility endpoint.\n    if os.environ.get(\"ZEP_API_URL\"):\n        raise ValueError(\"ZEP_API_URL is unsupported; unset it to use Zep Cloud\")\n\n    normalized_key = (api_key or Config.ZEP_API_KEY or \"\").strip()\n    if not normalized_key:\n        raise ValueError(\"ZEP_API_KEY 未配置\")\n\n    request_timeout = float(\n        timeout if timeout is not None else ZEP_HTTP_REQUEST_TIMEOUT_SECONDS\n    )\n    if request_timeout <= 0:\n        raise ValueError(\"Zep request timeout must be greater than 0\")\n    return _cached_zep_client(normalized_key, request_timeout)\n\n\ndef clear_zep_client_cache() -> None:\n    \"\"\"Clear cached clients. Intended for tests and controlled reconfiguration.\"\"\"\n\n    _cached_zep_client.cache_clear()\n\n\ndef is_retryable_zep_error(error: BaseException) -> bool:\n    \"\"\"Return whether a failed *read* is safe and useful to retry.\"\"\"\n\n    if isinstance(error, (httpx.TimeoutException, httpx.TransportError)):\n        return True\n    if isinstance(error, (ConnectionError, TimeoutError, OSError)):\n        return True\n    if isinstance(error, ZepApiError):\n        status_code = error.status_code","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/backend/app/utils/zep.py#L64-L100","documentation":"Raised by get_zep_client in backend/app/utils/zep.py when the resolved HTTP timeout is <= 0. The timeout is float(timeout) if the argument is not None, otherwise ZEP_HTTP_REQUEST_TIMEOUT_SECONDS — so a numeric string like \"0\" also lands here after float conversion, as does a negative constant misconfigured in settings. The client is constructed with this exact timeout, so a non-positive value is rejected before _cached_zep_client.","triggerScenarios":"Calling get_zep_client(timeout=0), timeout=-1, or timeout=\"0\"; or the ZEP_HTTP_REQUEST_TIMEOUT_SECONDS default being set to 0 in the settings module.","commonSituations":"Using 0 to mean 'system default timeout' (this API has no such sentinel — pass None instead); a timeout computed from config where an unset field defaults to 0; tests passing timeout=0 accidentally.","solutions":["Pass a positive timeout such as get_zep_client(timeout=30.0), or omit the argument to use the built-in default.","If the timeout is configurable, validate it as a positive number with a fallback default before calling.","Use None (not 0 or negatives) to request the library default."],"exampleFix":"# before\nclient = get_zep_client(api_key=key, timeout=cfg_timeout)  # cfg_timeout = 0\n\n# after\ntimeout = cfg_timeout if cfg_timeout and cfg_timeout > 0 else None\nclient = get_zep_client(api_key=key, timeout=timeout)","handlingStrategy":"validation","validationCode":"def safe_timeout(value: Any) -> float | None:\n    if value is None:\n        return None  # library default\n    t = float(value)\n    return t if t > 0 else None","typeGuard":"def is_positive_timeout(value: Any) -> TypeGuard[float]:\n    try:\n        return float(value) > 0\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    client = get_zep_client(timeout=t)\nexcept ValueError as e:\n    if \"timeout\" in str(e):\n        client = get_zep_client()  # library default\n    else:\n        raise","preventionTips":["Validate configurable timeouts as positive numbers with a documented default.","Use None (not 0) to request the library default timeout.","Unit-test the config path that produces the timeout value."],"tags":["validation","configuration","zep","timeout"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}