{"record":{"id":"55eb4ea0073c0c4f","repo":"jax-ml/jax","slug":"factor-names-have-to-start-with-a-letter-but-got-55eb4e","errorCode":null,"errorMessage":"Factor names have to start with a letter, but got '{char}'","messagePattern":"Factor names have to start with a letter, but got '(.+?)'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/custom_partitioning_sharding_rule.py","lineNumber":299,"sourceCode":"        if current_compound_dim is not None:\n          raise ValueError(\n              \"Compound factors should be one level, nested brackets are not\"\n              \" allowed\")\n        current_compound_dim = []\n      elif char == \")\":\n        if current_compound_dim is None:\n          raise ValueError(\"Brackets are not balanced\")\n        if len(current_compound_dim) <= 1:\n          raise ValueError(\"Brackets should contain at least two factors\")\n        value.append(CompoundFactor(*current_compound_dim))\n        current_compound_dim = None\n      elif char == \",\":\n        all_values.append(ArrayMapping(*value))\n        value = []\n    elif char == \"_\" or char.isdigit() or char.isalpha():\n      if current_factor is None:\n        if str.isdigit(char):\n          raise ValueError(f\"Factor names have to start with a letter, but got '{char}'\")\n        current_factor = char\n      else:\n        current_factor += char\n    else:\n      raise ValueError(f\"Unknown character '{char}'\")\n\n  if current_compound_dim is not None:\n    raise ValueError(f\"Brackets are not balanced in rule: '{rule}'\")\n  if current_factor is not None:\n    add_factor(current_factor)\n  all_values.append(ArrayMapping(*value))\n\n  return tuple(all_values)\n\ndef str_to_sdy_sharding_rule(rule: str, *,\n                             reduction_factors: tuple[str, ...] = (),\n                             need_replication_factors: tuple[str, ...] = (),\n                             permutation_factors: tuple[str, ...] = (),","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/custom_partitioning_sharding_rule.py#L281-L317","documentation":"Factor names in the rule must start with a letter (subsequent characters may be letters, digits, or '_'). A digit encountered where a new factor name begins raises this error.","triggerScenarios":"Rule token like '2i' or '4' standing alone, e.g. '2i,j->j'.","commonSituations":"Trying to encode numeric sizes directly in the rule instead of using symbolic factor names plus factor_sizes; names like '3d_weight'.","solutions":["Start factor names with a letter, e.g. 'd3' instead of '3d'","Move numeric sizes into factor_sizes, keeping symbolic names in the rule"],"exampleFix":"# before\nrule = '3d,f->f'\n# after\nrule = 'd3,f->f'  # with factor_sizes={'d3': ...} if needed","handlingStrategy":"validation","validationCode":"import re\nfor tok in re.findall(r'[A-Za-z0-9_]+', rule):\n    assert tok[0].isalpha(), f'factor name {tok!r} must start with a letter'","typeGuard":"import re\ndef names_start_with_letter(rule: str) -> bool:\n    return all(t[0].isalpha() for t in re.findall(r'[A-Za-z0-9_]+', rule) if t)","tryCatchPattern":null,"preventionTips":["Keep sizes in factor_sizes, not in names","Prefix digit-leading names with a letter"],"tags":["jax","sharding","naming","rule-syntax"],"backgroundTag":"invalid-identifier","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}