{"record":{"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":"exception","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/6a6b581b48225afa0b76912d1028c6035baee932/redis/driver_info.py#L105-L141","documentation":"add_upstream_driver (redis/driver_info.py:123) explicitly rejects a None driver_name with ValueError before any further validation, because None can never be a valid package-style name and would otherwise produce a confusing downstream TypeError when _validate_no_invalid_chars iterates it. driver_version is validated separately (error 426).","triggerScenarios":"Calling driver_info.add_upstream_driver(None, '1.0.0'), or passing a variable that resolved to None (e.g. a lookup that returned None for an unknown package) as the name argument.","commonSituations":"Auto-registration code that pulls a driver name from optional config or importlib.metadata and forwards it unconditionally; a conditional that left the name unset.","solutions":["Check that driver_name is a non-None string before calling add_upstream_driver, and skip registration when the name is unknown.","Default to a sane hardcoded lowercase name for your driver rather than forwarding an optional lookup result.","Log/warn when the name source is missing so silent skips are observable."],"exampleFix":"// before\ninfo.add_upstream_driver(config.get('driver_name'), VERSION)\n// after\nname = config.get('driver_name')\nif name:\n    info.add_upstream_driver(name, VERSION)","handlingStrategy":"validation","validationCode":"def register_if_name(info, name, version):\n    if name is not None:\n        info.add_upstream_driver(name, version)","typeGuard":"def has_name(name) -> bool:\n    return isinstance(name, str) and len(name) > 0","tryCatchPattern":null,"preventionTips":["Skip upstream-driver registration when the name source is missing rather than forwarding None.","Default to a hardcoded lowercase name for your driver.","Resolve names at import time and fail loud if a required name is absent."],"tags":["driver-info","validation","null-check","upstream-driver"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}