{"id":"0b1d8fd1533477b7","repo":"pypa/pip","slug":"empty-label","errorCode":null,"errorMessage":"Empty Label","messagePattern":"Empty Label","errorType":"validation","errorClass":"IDNAError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/idna/core.py","lineNumber":345,"sourceCode":"    (:func:`check_initial_combiner`), per-codepoint validity (PVALID,\n    CONTEXTJ, CONTEXTO classes from :rfc:`5892`), and the Bidi Rule\n    (:func:`check_bidi`).\n\n    :param label: The label to validate. ``bytes`` or ``bytearray`` input\n        is decoded as UTF-8 first.\n    :raises IDNAError: If the label is empty or fails a structural rule.\n    :raises InvalidCodepoint: If the label contains a DISALLOWED or\n        UNASSIGNED codepoint.\n    :raises InvalidCodepointContext: If a CONTEXTJ or CONTEXTO codepoint\n        is not valid in its context.\n    :raises IDNABidiError: If the Bidi Rule is violated.\n    \"\"\"\n    if len(label) > _max_input_length:\n        raise IDNAError(\"Label too long\")\n    if isinstance(label, (bytes, bytearray)):\n        label = label.decode(\"utf-8\")\n    if len(label) == 0:\n        raise IDNAError(\"Empty Label\")\n\n    # Reject on domain length rather than label length so support some UTS 46\n    # use cases, still reducing processing of label contextual rules\n    if not valid_string_length(label, trailing_dot=True):\n        raise IDNAError(\"Label too long\")\n\n    check_nfc(label)\n    check_hyphen_ok(label)\n    check_initial_combiner(label)\n\n    for pos, cp in enumerate(label):\n        cp_value = ord(cp)\n        if intranges_contain(cp_value, idnadata.codepoint_classes[\"PVALID\"]):\n            continue\n        if intranges_contain(cp_value, idnadata.codepoint_classes[\"CONTEXTJ\"]):\n            try:\n                if not valid_contextj(label, pos):\n                    raise InvalidCodepointContext(f\"Joiner {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}\")","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/idna/core.py#L327-L363","documentation":"IDNAError raised by check_label when, after bytes-to-str decoding, the label has length 0. An empty label is structurally invalid: DNS does not permit zero-length labels inside a name (only the trailing root label, represented separately).","triggerScenarios":"Calling check_label/alabel with '' or b''; also reached when a domain like 'a..b' is split and an interior empty segment is passed to alabel (encode() guards this earlier with 'Empty label', but direct check_label callers see 'Empty Label').","commonSituations":"Double dots in user-typed hostnames ('example..com'); trailing-dot handling that leaves an empty segment; concatenation producing 'a.'+''; sanitizers that strip everything leaving ''.","solutions":["Reject empty labels at the input boundary before IDNA.","Collapse consecutive dots / strip trailing dots before splitting: re.sub(r'\\.+', '.', s).rstrip('.').","Treat empty input as an application-level error with a clear message rather than passing to idna."],"exampleFix":"# before\nparts = 'a..b'.split('.')\nfor p in parts: idna.check_label(p)  # '' -> Empty Label\n\n# after\nparts = [p for p in 'a..b'.split('.') if p]\nfor p in parts: idna.check_label(p)","handlingStrategy":"validation","validationCode":"def reject_empty_labels(domain: str) -> list:\n    parts = [p for p in domain.split('.') if p != '']\n    if not parts:\n        raise ValueError('empty domain')\n    return parts","typeGuard":"def has_no_empty_labels(domain: str) -> bool:\n    return all(p != '' for p in domain.split('.')) and domain != ''","tryCatchPattern":"from idna import IDNAError\ntry:\n    idna.check_label(label)\nexcept IDNAError as e:\n    if 'Empty' in str(e):\n        # skip this label rather than aborting the whole domain\n        return None\n    raise","preventionTips":["Collapse consecutive dots and strip trailing dots before splitting: re.sub(r'\\.+', '.', s).rstrip('.').","Filter out empty segments after split.","Reject empty input at the application boundary with a clear error."],"tags":["idna","dns","validation","empty-input","pip"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}