{"record":{"id":"5ebbed70e2cd6ad5","repo":"pytorch/pytorch","slug":"ellipsis-is-not-an-allowed-axis-identifier","errorCode":null,"errorMessage":"'{_ellipsis}' is not an allowed axis identifier","messagePattern":"'(.+?)' is not an allowed axis identifier","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"functorch/einops/_parsing.py","lineNumber":230,"sourceCode":") -> tuple[ParsedExpression, ParsedExpression]:\n    \"\"\"Parse an `einops`-style pattern into a left-hand side and right-hand side `ParsedExpression` object.\n\n    Args:\n        pattern (str): the `einops`-style rearrangement pattern\n        axes_lengths (Mapping[str, int]): any additional length specifications for dimensions\n\n    Returns:\n       tuple[ParsedExpression, ParsedExpression]: a tuple containing the left-hand side and right-hand side expressions\n    \"\"\"\n    # adapted from einops.einops._prepare_transformation_recipe\n    # https://github.com/arogozhnikov/einops/blob/230ac1526c1f42c9e1f7373912c7f8047496df11/einops/einops.py\n    try:\n        left_str, right_str = pattern.split(\"->\")\n    except ValueError:\n        raise ValueError(\"Pattern must contain a single '->' separator\") from None\n\n    if _ellipsis in axes_lengths:\n        raise ValueError(f\"'{_ellipsis}' is not an allowed axis identifier\")\n\n    left = ParsedExpression(left_str)\n    right = ParsedExpression(right_str)\n\n    if not left.has_ellipsis and right.has_ellipsis:\n        raise ValueError(\n            f\"Ellipsis found in right side, but not left side of a pattern {pattern}\"\n        )\n    if left.has_ellipsis and left.has_ellipsis_parenthesized:\n        raise ValueError(\n            f\"Ellipsis is parenthesis in the left side is not allowed: {pattern}\"\n        )\n\n    return left, right\n\n\ndef validate_rearrange_expressions(\n    left: ParsedExpression, right: ParsedExpression, axes_lengths: Mapping[str, int]","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/pytorch/pytorch/blob/dcd2ecae775af66439b7ede4e7a82540b058c59c/functorch/einops/_parsing.py#L212-L248","documentation":"Thrown in functorch/einops `_parsing.py` when the user-supplied `axes_lengths` mapping contains the ellipsis symbol (`'…'`, or `'...'` converted during parsing) as a key. The ellipsis stands for 'all remaining axes' and cannot be assigned a fixed length.","triggerScenarios":"Calling `rearrange(t, '... h -> h', **{'...': 3})` or otherwise passing an ellipsis key/keyword in the length specification.","commonSituations":"Programmatically forwarding a config dict of axis lengths that includes a placeholder for the ellipsis; misunderstanding that `...` is a wildcard, not a nameable axis.","solutions":["Remove the ellipsis entry from `axes_lengths`","If you need to fix the number of remaining axes, name them explicitly in the pattern instead of using `...`"],"exampleFix":"# before\ny = rearrange(x, '... h -> h', **{'...': 3})\n\n# after\ny = rearrange(x, 'b c h -> h')  # name the axes explicitly","handlingStrategy":"validation","validationCode":"_ELLIPSIS = \"\\u2026\"\n\ndef axes_lengths_ok(axes_lengths) -> bool:\n    return _ELLIPSIS not in axes_lengths and \"...\" not in axes_lengths","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never put '...' or '…' in axes_lengths; the ellipsis is a wildcard","Name axes explicitly when you need fixed lengths"],"tags":["einops","parsing","axes-lengths","ellipsis"],"backgroundTag":null,"analyzedSha":"dcd2ecae775af66439b7ede4e7a82540b058c59c","analyzedAt":"2026-08-14T19:21:26.615Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}