{"id":"1b6c6baf05b6fc3d","repo":"redis/redis-py","slug":"get-node-requires-one-of-the-following-1-node-na","errorCode":null,"errorMessage":"get_node requires one of the following: 1. node name 2. host and port","messagePattern":"get_node requires one of the following: 1\\. node name 2\\. host and port","errorType":"validation","errorClass":"DataError","httpStatus":null,"severity":"error","filePath":"redis/asyncio/cluster.py","lineNumber":2049,"sourceCode":"            self._event_dispatcher = EventDispatcher()\n        else:\n            self._event_dispatcher = event_dispatcher\n\n    def get_node(\n        self,\n        host: Optional[str] = None,\n        port: Optional[int] = None,\n        node_name: Optional[str] = None,\n    ) -> Optional[\"ClusterNode\"]:\n        if host and port:\n            # the user passed host and port\n            if host == \"localhost\":\n                host = socket.gethostbyname(host)\n            return self.nodes_cache.get(get_node_name(host=host, port=port))\n        elif node_name:\n            return self.nodes_cache.get(node_name)\n        else:\n            raise DataError(\n                \"get_node requires one of the following: 1. node name 2. host and port\"\n            )\n\n    def set_nodes(\n        self,\n        old: Dict[str, \"ClusterNode\"],\n        new: Dict[str, \"ClusterNode\"],\n        remove_old: bool = False,\n    ) -> None:\n        if remove_old:\n            for name in list(old.keys()):\n                if name not in new:\n                    # Node is removed from cache before disconnect starts,\n                    # so it won't be found in lookups during disconnect\n                    # Mark active connections so in-flight commands can\n                    # finish, then disconnect them when their current\n                    # operation completes. Free connections can be\n                    # disconnected immediately.","sourceCodeStart":2031,"sourceCodeEnd":2067,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/asyncio/cluster.py#L2031-L2067","documentation":"A DataError raised by NodesManager.get_node() when called with neither a node_name nor a (host, port) pair. get_node() needs exactly one identifier to look up a node in the nodes_cache: either the cluster node name (node id) or a host+port tuple. With no identifier there is nothing to look up, so it rejects the call rather than returning an ambiguous result.","triggerScenarios":"Calling rc.get_node() with no arguments; calling rc.get_node(host='1.2.3.4') without port, or rc.get_node(port=6379) without host — the branch logic at cluster.py:2041-2048 requires both host AND port for that path, or a node_name.","commonSituations":"Introspection helper code that calls get_node() expecting the default/current node; passing only host because the caller assumed a default port; refactoring that drops one of the two coordinate arguments.","solutions":["Provide both host and port: rc.get_node(host='10.0.0.1', port=6379).","Or provide the node name: rc.get_node(node_name='<cluster-node-id>').","If you want the default node, use rc.get_default_node() instead of get_node()."],"exampleFix":"// before\nnode = rc.get_node(host='10.0.0.1')\n\n// after\nnode = rc.get_node(host='10.0.0.1', port=6379)","handlingStrategy":"validation","validationCode":"from typing import Optional\n\ndef lookup_node(rc, host=None, port=None, node_name=None):\n    if node_name:\n        return rc.get_node(node_name=node_name)\n    if host and port:\n        return rc.get_node(host=host, port=port)\n    raise ValueError('Provide node_name, or both host and port')","typeGuard":"from typing import Optional\n\ndef has_node_identifier(host: Optional[str], port: Optional[int], node_name: Optional[str]) -> bool:\n    return bool(node_name) or (bool(host) and bool(port))","tryCatchPattern":"from redis.exceptions import DataError\n\ntry:\n    node = rc.get_node(host=h, port=p, node_name=n)\nexcept DataError as e:\n    if 'get_node requires' in str(e):\n        raise ValueError('Pass either node_name or (host, port)') from e\n    raise","preventionTips":["Always pass host and port together, or node_name alone.","Use rc.get_default_node() when you want the current default rather than get_node() with no args.","Centralize node lookups in a helper that validates the identifier pair."],"tags":["redis-cluster","node-lookup","dataerror","api-usage"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}