{"record":{"id":"bbb80c97ead7a88b","repo":"jax-ml/jax","slug":"all-arrays-must-have-the-same-rank-got-len-arr-s","errorCode":null,"errorMessage":"All arrays must have the same rank, got {len(arr.shape)} at index {i} (expected {rank})","messagePattern":"All arrays must have the same rank, got (.+?) at index (.+?) \\(expected (.+?)\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/experimental/mosaic/gpu/fragmented_array.py","lineNumber":5354,"sourceCode":"    axis: int = 0,\n) -> FragmentedArray:\n  \"\"\"Concatenates fragmented arrays along the specified axis.\"\"\"\n  if not arrays:\n    raise ValueError(\"Need at least one array to concatenate\")\n  arr0 = arrays[0]\n  rank = len(arr0.shape)\n  if not -rank <= axis < rank:\n    raise ValueError(f\"{axis=} is out of bounds for array of {rank=}\")\n  if axis < 0:\n    axis += rank\n\n  if len(arrays) == 1:\n    return arr0\n\n  new_shape = list(arr0.shape)\n  for i, arr in enumerate(arrays[1:], start=1):\n    if len(arr.shape) != rank:\n      raise ValueError(\n          f\"All arrays must have the same rank, got {len(arr.shape)} at index\"\n          f\" {i} (expected {rank})\"\n      )\n    if arr.mlir_dtype != arr0.mlir_dtype:\n      raise ValueError(\n          f\"All arrays must have the same dtype, got {arr.mlir_dtype} at\"\n          f\" index {i} (expected {arr0.mlir_dtype})\"\n      )\n    if arr.is_signed != arr0.is_signed:\n      raise ValueError(\n          f\"All arrays must have the same signedness, got {arr.is_signed} at\"\n          f\" index {i} (expected {arr0.is_signed})\"\n      )\n    for d in range(rank):\n      if d != axis and arr.shape[d] != arr0.shape[d]:\n        raise ValueError(\n            \"All arrays must have matching shapes along non-concatenated\"\n            f\" dimensions, got shape {arr.shape} at index {i} (expected dim\"","sourceCodeStart":5336,"sourceCodeEnd":5372,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/experimental/mosaic/gpu/fragmented_array.py#L5336-L5372","documentation":"concatenate requires all FragmentedArrays to share the same rank (number of dimensions) because registers are concatenated with np.concatenate, which needs uniformly shaped arrays apart from the concat axis. A mismatched rank raises ValueError with the offending index.","triggerScenarios":"Mixing a 2D FragmentedArray with a 3D one in the arrays list, e.g. concatenate([a_2d, b_3d]).","commonSituations":"Some pipeline stages adding or removing a unit dimension (expand_dims/squeeze) so fragments drift in rank; heterogeneously-built fragments appended to one list; refactoring from numpy where broadcasting silently handled rank differences.","solutions":["Normalize ranks before concatenating: expand or squeeze dims so every array has rank equal to arrays[0].","Fix the producing op that introduced the extra/missing dimension (check layout/shape construction).","Add a pre-call assert: assert all(len(a.shape) == len(arrays[0].shape) for a in arrays)."],"exampleFix":"# before\nout = FragmentedArray.concatenate([a, b], axis=0)  # a rank 2, b rank 3\n# after\nb2 = b.reshape_with_layout(...) # or store/load so ranks match\nout = FragmentedArray.concatenate([a, b2], axis=0)","handlingStrategy":"validation","validationCode":"rank = len(arrays[0].shape)\nbad = [i for i, a in enumerate(arrays) if len(a.shape) != rank]\nassert not bad, f'rank mismatch at {bad}'\nout = FragmentedArray.concatenate(arrays, axis=axis)","typeGuard":"def all_same_rank(arrays) -> bool:\n    r = len(arrays[0].shape)\n    return all(len(a.shape) == r for a in arrays)","tryCatchPattern":null,"preventionTips":["Expand/squeeze dims uniformly across pipeline stages.","Build fragments from a single templated helper.","Unit-test concatenate with representative fragment sets."],"tags":["jax","mosaic-gpu","validation","rank-mismatch"],"backgroundTag":"ndim-shape-mismatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}