{"id":"9aac042e86bda15a","repo":"redis/redis-py","slug":"driver-name-must-not-be-none","errorCode":null,"errorMessage":"Driver name must not be None","messagePattern":"Driver name must not be None","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/driver_info.py","lineNumber":123,"sourceCode":"    @property\n    def upstream_drivers(self) -> List[str]:\n        \"\"\"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)","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/driver_info.py#L105-L141","documentation":"Raised as ValueError by DriverInfo.add_upstream_driver (redis/driver_info.py:123) when driver_name is None. A None name cannot be formatted into the CLIENT SETINFO LIB-NAME payload, so it is rejected explicitly before any further validation runs.","triggerScenarios":"Calling add_upstream_driver(None, version) — typically because a variable holding the name was uninitialized, came back None from a config lookup, or a default argument leaked through.","commonSituations":"Reading driver metadata from an env var / config that returned None; an optional field whose default propagated; a refactor that dropped the name argument.","solutions":["Ensure the name is a non-None string before calling add_upstream_driver.","Default the name to a real identifier (your package's __title__) when the source is optional.","Validate config at load time so None never reaches the DriverInfo API."],"exampleFix":"// before\ninfo.add_upstream_driver(os.environ.get('DRIVER_NAME'), '1.0.0')  # None if unset\n\n// after\ninfo.add_upstream_driver(os.environ.get('DRIVER_NAME') or 'my-driver', '1.0.0')","handlingStrategy":"validation","validationCode":"name = os.environ.get('DRIVER_NAME') or 'my-driver'\nassert name is not None, 'driver name missing'\ninfo.add_upstream_driver(name, version)","typeGuard":"def is_nonempty_str(v) -> bool:\n    return isinstance(v, str) and v != ''","tryCatchPattern":null,"preventionTips":["Default optional name fields to a concrete identifier rather than None.","Validate config-derived names at startup and fail loudly if missing.","Never pass an unvalidated os.environ.get(...) result straight into add_upstream_driver."],"tags":["driver-info","client-setinfo","validation","valueerror","none"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}