{"record":{"id":"eafe476a7fae1930","repo":"jax-ml/jax","slug":"cluster-names-must-have-the-same-length-as-cluster","errorCode":null,"errorMessage":"cluster_names must have the same length as cluster, got {self}.","messagePattern":"cluster_names must have the same length as cluster, got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/pallas/mosaic_gpu/core.py","lineNumber":1646,"sourceCode":"class Mesh(pallas_core.Mesh):\n  grid: Sequence[int] = ()\n  grid_names: Sequence[str] = ()\n  cluster: Sequence[int] = ()\n  cluster_names: Sequence[str] = ()\n  # Those are NOT CUDA threads. On Hopper they correspond to warpgroups.\n  num_threads: int | None = None\n  thread_name: str | None = None\n  kernel_name: str | None = None\n\n  def __post_init__(self):\n    if len(self.cluster) > 3:\n      raise ValueError(f\"cluster= must be at most 3D, got {self}.\")\n    if len(self.grid_names) != len(self.grid):\n      raise ValueError(\n          f\"grid_names must have the same length as grid, got {self}.\"\n      )\n    if len(self.cluster_names) != len(self.cluster):\n      raise ValueError(\n          f\"cluster_names must have the same length as cluster, got {self}.\"\n      )\n    if (self.thread_name is None) != (self.num_threads is None):\n      raise ValueError(\n          \"num_threads and thread_name must be either both set or both None,\"\n          f\" got {self}\"\n      )\n    max_mosaic_threads = 2048 // 128\n    if self.num_threads is not None and self.num_threads > max_mosaic_threads:\n      raise ValueError(\n          \"Requested too many CUDA threads per block. Each Mosaic thread\"\n          f\" corresponds to 128 CUDA threads. At most {max_mosaic_threads}\"\n          f\" are supported, got {self}\"\n      )\n    object.__setattr__(self, \"grid\", tuple(self.grid))\n    object.__setattr__(self, \"grid_names\", tuple(self.grid_names))\n    object.__setattr__(self, \"cluster\", tuple(self.cluster))\n    object.__setattr__(self, \"cluster_names\", tuple(self.cluster_names))","sourceCodeStart":1628,"sourceCodeEnd":1664,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/pallas/mosaic_gpu/core.py#L1628-L1664","documentation":"Launch-config dataclass validation: `cluster_names` must have the same length as `cluster`. Cluster axis names are used for lax.axis_index-style queries inside the kernel, so a mismatch is rejected at construction.","triggerScenarios":"Passing `cluster=(2, 2)` with `cluster_names=('cq',)` (lengths differ) to the Mosaic GPU launch/config dataclass.","commonSituations":"Changing cluster dimensionality (e.g. after hitting the 3D cluster limit) without updating names; deriving cluster_names from grid_names programmatically with an off-by-one or wrong source tuple.","solutions":["Align lengths: cluster=(2, 2), cluster_names=('cq', 'ck')","Re-generate names with a comprehension: cluster_names=tuple(f'c{i}' for i in range(len(cluster)))"],"exampleFix":"// before\ncluster=(2, 2)\ncluster_names=('cq',)\n\n// after\ncluster=(2, 2)\ncluster_names=('cq', 'ck')","handlingStrategy":"validation","validationCode":"assert len(cluster) == len(cluster_names), (cluster, cluster_names)","typeGuard":"def cluster_names_valid(cluster, names) -> bool:\n    return len(names) == len(cluster)","tryCatchPattern":"try:\n    cfg = LaunchConfig(cluster=c, cluster_names=names)\nexcept ValueError:\n    names = tuple(f'c{i}' for i in range(len(c)))\n    cfg = LaunchConfig(cluster=c, cluster_names=names)","preventionTips":["Derive cluster_names programmatically from cluster","Update names whenever cluster dimensionality changes","Test config construction in CI"],"tags":["jax","pallas","mosaic-gpu","launch-config","validation","shape-mismatch"],"backgroundTag":"config-length-mismatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}