{"record":{"id":"52b7df978c049ecc","repo":"python/cpython","slug":"2-tuple-is-expected","errorCode":null,"errorMessage":"2-tuple is expected","messagePattern":"2-tuple is expected","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"Lib/asyncio/base_events.py","lineNumber":1442,"sourceCode":"                        if stat.S_ISSOCK(os.stat(local_addr).st_mode):\n                            os.remove(local_addr)\n                    except FileNotFoundError:\n                        pass\n                    except OSError as err:\n                        # Directory may have permissions only to create socket.\n                        logger.error('Unable to check or remove stale UNIX '\n                                     'socket %r: %r',\n                                     local_addr, err)\n\n                addr_pairs_info = (((family, proto),\n                                    (local_addr, remote_addr)), )\n            else:\n                # join address by (family, protocol)\n                addr_infos = {}  # Using order preserving dict\n                for idx, addr in ((0, local_addr), (1, remote_addr)):\n                    if addr is not None:\n                        if not (isinstance(addr, tuple) and len(addr) == 2):\n                            raise TypeError('2-tuple is expected')\n\n                        infos = await self._ensure_resolved(\n                            addr, family=family, type=socket.SOCK_DGRAM,\n                            proto=proto, flags=flags, loop=self)\n                        if not infos:\n                            raise OSError('getaddrinfo() returned empty list')\n\n                        for fam, _, pro, _, address in infos:\n                            key = (fam, pro)\n                            if key not in addr_infos:\n                                addr_infos[key] = [None, None]\n                            addr_infos[key][idx] = address\n\n                # each addr has to have info for each (family, proto) pair\n                addr_pairs_info = [\n                    (key, addr_pair) for key, addr_pair in addr_infos.items()\n                    if not ((local_addr and addr_pair[0] is None) or\n                            (remote_addr and addr_pair[1] is None))]","sourceCodeStart":1424,"sourceCodeEnd":1460,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/asyncio/base_events.py#L1424-L1460","documentation":"Raised by create_datagram_endpoint() when local_addr or remote_addr is not a 2-tuple. For INET families the address form is (host, port); passing a bare string, a 3/4-tuple, a list, or None-ish values triggers this TypeError before any name resolution.","triggerScenarios":"loop.create_datagram_endpoint(factory, remote_addr='127.0.0.1') or remote_addr=('127.0.0.1', 9000, 0, 0) or remote_addr=['127.0.0.1', 9000].","commonSituations":"Passing a pre-resolved getaddrinfo() 5-tuple instead of (host, port); forgetting to unpack a config pair; using a list literal instead of a tuple.","solutions":["Pass exactly a 2-tuple of (host, port), e.g. ('127.0.0.1', 9999)","If the value came from getaddrinfo(), take entry[4][0:2] or feed the original host/port instead","Unpack config values: remote_addr=tuple(addr_pair[:2])"],"exampleFix":"# before\nawait loop.create_datagram_endpoint(factory, remote_addr=('127.0.0.1', 53, 0, 0))\n\n# after\nawait loop.create_datagram_endpoint(factory, remote_addr=('127.0.0.1', 53))","handlingStrategy":"validation","validationCode":"def as_addr_pair(a) -> tuple:\n    if not (isinstance(a, tuple) and len(a) == 2):\n        raise TypeError(f'expected (host, port) 2-tuple, got {a!r}')\n    return a\nlocal_addr = as_addr_pair(local_addr) if local_addr else None\nremote_addr = as_addr_pair(remote_addr) if remote_addr else None","typeGuard":"def is_host_port(a: object) -> TypeGuard[tuple[str, int]]:\n    return isinstance(a, tuple) and len(a) == 2 and isinstance(a[0], str) and isinstance(a[1], int)","tryCatchPattern":null,"preventionTips":["Never feed raw getaddrinfo() results back as addresses; use the original host/port","Parse config into (host, port) tuples once at load time"],"tags":["asyncio","udp","datagram","type-error"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}