{"id":"602a06e2a83ee3b4","repo":"redis/redis-py","slug":"driver-version-must-not-be-none","errorCode":null,"errorMessage":"Driver version must not be None","messagePattern":"Driver version must not be None","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/driver_info.py","lineNumber":125,"sourceCode":"        \"\"\"Return a copy of the upstream driver entries.\n\n        Each entry is in the form ``\"driver-name_vversion\"``.\n        \"\"\"\n\n        return list(self._upstream)\n\n    def add_upstream_driver(\n        self, driver_name: str, driver_version: str\n    ) -> \"DriverInfo\":\n        \"\"\"Add an upstream driver to this instance and return self.\n\n        The most recently added driver appears first in :pyattr:`formatted_name`.\n        \"\"\"\n\n        if driver_name is None:\n            raise ValueError(\"Driver name must not be None\")\n        if driver_version is None:\n            raise ValueError(\"Driver version must not be None\")\n\n        _validate_driver_name(driver_name)\n        _validate_driver_version(driver_version)\n\n        entry = _format_driver_entry(driver_name, driver_version)\n        # insert at the beginning so latest is first\n        self._upstream.insert(0, entry)\n        return self\n\n    @property\n    def formatted_name(self) -> Optional[str]:\n        \"\"\"Return the base name with upstream drivers encoded, if any.\n\n        With no upstream drivers, this is just :pyattr:`name`. Otherwise::\n\n            name(driver1_vX;driver2_vY)\n        \"\"\"\n","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/driver_info.py#L107-L143","documentation":"Raised as ValueError by DriverInfo.add_upstream_driver (redis/driver_info.py:125) when driver_version is None. Like the name, a None version cannot be encoded into the LIB-VER portion of the CLIENT SETINFO payload, so it is rejected before formatting.","triggerScenarios":"Calling add_upstream_driver(name, None) — e.g. a version read from package metadata or git that returned None, or a missing/optional version argument.","commonSituations":"importlib.metadata.version() failing under a fallback that yields None; a version derived from a git tag that was empty in CI; an optional version field whose default leaked through.","solutions":["Resolve a concrete version string before calling add_upstream_driver.","Default to importlib.metadata.version('your-pkg') or a hardcoded fallback version.","Fail loudly at startup if the version cannot be determined rather than passing None."],"exampleFix":"// before\nfrom importlib import metadata\ninfo.add_upstream_driver('my-driver', metadata.version('my-driver') if pkg_found else None)\n\n// after\nfrom importlib import metadata\nver = metadata.version('my-driver') if pkg_found else '0.0.0'\ninfo.add_upstream_driver('my-driver', ver)","handlingStrategy":"validation","validationCode":"from importlib import metadata\ntry:\n    version = metadata.version('my-driver')\nexcept metadata.PackageNotFoundError:\n    version = '0.0.0'\ninfo.add_upstream_driver(name, version)","typeGuard":"def is_nonempty_str(v) -> bool:\n    return isinstance(v, str) and v != ''","tryCatchPattern":null,"preventionTips":["Resolve the version to a concrete string (importlib.metadata.version with a fallback) before passing it in.","Fail at startup if the version is unknown rather than passing None.","For CI-built packages, ensure the version is baked in, not read live from an unreliable source."],"tags":["driver-info","client-setinfo","validation","valueerror","none"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}