{"record":{"id":"7dc815cbbf7db401","repo":"jax-ml/jax","slug":"kind-must-be-a-tuple-of-factors","errorCode":null,"errorMessage":"{kind} must be a tuple of factors","messagePattern":"(.+?) must be a tuple of factors","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/custom_partitioning_sharding_rule.py","lineNumber":163,"sourceCode":"          f\"Factor {factor} is not used in the rule, but size is provided\")\n\n    # Check that factors that are used for a whole dimension aren't in\n    # factor_sizes and factors that are never used for a whole dimension are\n    # in factor_sizes.\n    for factor, inferable in factors_inferrable.items():\n      if factor not in factor_sizes and not inferable:\n        raise ValueError(\n          f\"Factor {factor} is only used in compound factors; must specify\"\n          \" its size\")\n      if factor in factor_sizes and inferable:\n        raise ValueError(\n          f\"Factor {factor} represents a whole dimension; do not specify its\"\n          \" size\")\n\n    special_factors = set()\n    def check_special_factors(kind, factors):\n      if not isinstance(factors, tuple):\n        raise ValueError(f\"{kind} must be a tuple of factors\")\n\n      if len(factors) != len(set(factors)):\n        raise ValueError(f\"{kind} contains duplicated factors\")\n\n      for factor in factors:\n        if factor not in factors_inferrable:\n          raise ValueError(\n            f\"Factor {factor} in {kind} is not used in the rule\")\n        if factor in special_factors:\n          raise ValueError(f\"Factor {factor} can only be in one of the \"\n              f\"reduction, need replication, or permutation factor sets.\")\n        special_factors.add(factor)\n\n    check_special_factors(\"reduction_factors\", reduction_factors)\n    check_special_factors(\"need_replication_factors\", need_replication_factors)\n    check_special_factors(\"permutation_factors\", permutation_factors)\n\n    self.operand_mappings = operand_mappings","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/custom_partitioning_sharding_rule.py#L145-L181","documentation":"check_special_factors validates that reduction_factors, need_replication_factors, or permutation_factors is a tuple of factor names. A non-tuple (list, string, None where a tuple is expected) triggers this error.","triggerScenarios":"Passing reduction_factors=['m'] (a list) or a bare string 'm' instead of ('m',) to def_partition / str_to_sdy_sharding_rule.","commonSituations":"Using a list literal out of habit; passing a single factor as a string instead of a 1-tuple.","solutions":["Wrap the factors in a tuple: reduction_factors=('m',)","Convert existing lists with tuple(...) before passing"],"exampleFix":"# before\nreduction_factors = ['m']\n# after\nreduction_factors = ('m',)","handlingStrategy":"type-guard","validationCode":"assert isinstance(reduction_factors, tuple) and isinstance(need_replication_factors, tuple) and isinstance(permutation_factors, tuple)","typeGuard":"def is_factor_tuple(x) -> bool:\n    return isinstance(x, tuple) and all(isinstance(f, str) for f in x)","tryCatchPattern":null,"preventionTips":["Always use tuple literals ('m',) not lists or bare strings","Lint calls with a wrapper that coerces tuple(x)"],"tags":["jax","sharding","type-error","tuple"],"backgroundTag":"wrong-argument-type","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}