{"id":"1930cdbd0b76730a","repo":"pypa/pip","slug":"invalid-direction-for-codepoint-at-position-idx","errorCode":null,"errorMessage":"Invalid direction for codepoint at position {idx} in a right-to-left label","messagePattern":"Invalid direction for codepoint at position (.+?) in a right-to-left label","errorType":"validation","errorClass":"IDNABidiError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/idna/core.py","lineNumber":146,"sourceCode":"\n    # Bidi rule 1\n    direction = unicodedata.bidirectional(label[0])\n    if direction in _bidi_rtl_first:\n        rtl = True\n    elif direction == \"L\":\n        rtl = False\n    else:\n        raise IDNABidiError(f\"First codepoint in label {label!r} must be directionality L, R or AL\")\n\n    valid_ending = False\n    number_type: Optional[str] = None\n    for idx, cp in enumerate(label, 1):\n        direction = unicodedata.bidirectional(cp)\n\n        if rtl:\n            # Bidi rule 2\n            if direction not in _bidi_rtl_allowed:\n                raise IDNABidiError(f\"Invalid direction for codepoint at position {idx} in a right-to-left label\")\n            # Bidi rule 3\n            if direction in _bidi_rtl_valid_ending:\n                valid_ending = True\n            elif direction != \"NSM\":\n                valid_ending = False\n            # Bidi rule 4\n            if direction in _bidi_rtl_numeric:\n                if not number_type:\n                    number_type = direction\n                elif number_type != direction:\n                    raise IDNABidiError(\"Can not mix numeral types in a right-to-left label\")\n        else:\n            # Bidi rule 5\n            if direction not in _bidi_ltr_allowed:\n                raise IDNABidiError(f\"Invalid direction for codepoint at position {idx} in a left-to-right label\")\n            # Bidi rule 6\n            if direction in _bidi_ltr_valid_ending:\n                valid_ending = True","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/idna/core.py#L128-L164","documentation":"IDNABidiError from check_bidi Bidi Rule 2: in a right-to-left label every codepoint must have a bidi category in the allowed RTL set {R, AL, AN, EN, ES, CS, ET, ON, BN, NSM}. Any codepoint with a category outside that set (e.g. an L-category Latin letter mixed into an Arabic/Hebrew label) is illegal at the given position.","triggerScenarios":"Mixing a Latin/different-script L-category character into an otherwise RTL label, e.g. 'العxرب' (Latin 'x' inside Arabic). The position reported is the offending codepoint's index (1-based).","commonSituations":"Concatenating user-supplied fragments from different scripts into a single DNS label; brand names that splice a Latin trademark into a localized Arabic/Hebrew subdomain; copy-paste errors inserting invisible L-category characters.","solutions":["Keep each RTL label script-pure; move Latin fragments to a separate label or replace with a transliteration.","Audit the offending position reported in the message and remove or remap that codepoint.","Run a script-consistency check (idnadata.scripts) before IDNA encoding."],"exampleFix":"# before\nidna.encode('العxرب')  # Invalid direction at position of 'x'\n\n# after\nidna.encode('العرب')","handlingStrategy":"validation","validationCode":"import unicodedata\n_RTL_ALLOWED = {'R','AL','AN','EN','ES','CS','ET','ON','BN','NSM'}\ndef is_pure_rtl_label(label: str) -> bool:\n    return all(unicodedata.bidirectional(c) in _RTL_ALLOWED for c in label)","typeGuard":"import unicodedata\ndef is_rtl_label_clean(label: str) -> bool:\n    return all(unicodedata.bidirectional(c) in {'R','AL','AN','EN','ES','CS','ET','ON','BN','NSM'} for c in label)","tryCatchPattern":"from idna import IDNABidiError\ntry:\n    idna.encode(label)\nexcept IDNABidiError as e:\n    if 'Invalid direction' in str(e) and 'right-to-left' in str(e):\n        # remove L-category codepoints and retry, or reject\n        raise ValueError('mixed scripts in RTL label') from e\n    raise","preventionTips":["Keep each RTL (Arabic/Hebrew) label script-pure; do not splice Latin characters into it.","Audit the position reported in the error message.","Run a script-consistency check (idnadata.scripts) before encoding."],"tags":["idna","bidi","rfc5893","rtl","pip"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}