{"record":{"id":"61e8830f58817a56","repo":"jax-ml/jax","slug":"perm-passed-to-jax-lax-ppermute-must-be-a-list","errorCode":null,"errorMessage":"`perm` passed to `jax.lax.ppermute` must be a list or a tuple. Got perm of type {type(perm)}","messagePattern":"`perm` passed to `jax\\.lax\\.ppermute` must be a list or a tuple\\. Got perm of type (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/parallel.py","lineNumber":409,"sourceCode":"      ``(source_index, destination_index)``\n      pairs that encode how the mapped axis named ``axis_name`` should be\n      shuffled. The integer values are treated as indices into the mapped axis\n      ``axis_name``. Any two pairs should not have the same source index or the\n      same destination index. For each index of the axis ``axis_name`` that does\n      not correspond to a destination index in ``perm``, the corresponding\n      values in the result are filled with zeros of the appropriate type.\n\n  Returns:\n    Array(s) with the same shape as ``x`` with slices along the axis\n    ``axis_name`` gathered from ``x`` according to the permutation ``perm``.\n  \"\"\"\n  return _ppermute_is_async(x, axis_name, perm, is_async=False)\n\ndef _ppermute_is_async(x, axis_name, perm, is_async=False):\n  if not isinstance(axis_name, (list, tuple)):\n    axis_name = (axis_name,)\n  if not isinstance(perm, (list, tuple)):\n    raise TypeError(\n        \"`perm` passed to `jax.lax.ppermute` must be a list or a tuple. Got\"\n        f\" perm of type {type(perm)}\")\n  def bind(leaf):\n    leaf = insert_collective_pvary(axis_name, leaf)\n    prim = ppermute_start_p if is_async else ppermute_p\n    return prim.bind(leaf, axis_name=axis_name, perm=tuple(map(tuple, perm)))\n  return tree_util.tree_map(bind, x)\n\n\ndef psend(x, axis_name, perm):\n  \"\"\"Perform a collective send according to the permutation ``perm``.\n\n  If ``x`` is a pytree then the result is equivalent to mapping this function to\n  each leaf in the tree.\n\n  This function is an analog of the Send HLO.\n\n  Args:","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/parallel.py#L391-L427","documentation":"jax.lax.ppermute requires perm to be a list or tuple of (source, destination) index pairs describing a permutation across the mapped axis. Passing e.g. a dict, numpy array, or generator raises TypeError before any device communication.","triggerScenarios":"ppermute(x, 'i', np.array([[0,1],[1,0]])) or perm as a dict/generator/iterator.","commonSituations":"Passing a numpy array of pairs from routing logic; converting perm data from another format and forgetting to list()-ify.","solutions":["Convert to a list/tuple of 2-tuples: perm = [(int(a), int(b)) for a, b in perm]","If using pshuffle semantics (flat permutation), call pshuffle(x, axis_name, perm) which builds the inverse pairs for you"],"exampleFix":"// before\ny = jax.lax.ppermute(x, 'i', np.array([[0,1],[1,0]]))\n\n// after\ny = jax.lax.ppermute(x, 'i', [(0,1),(1,0)])","handlingStrategy":"type-guard","validationCode":"assert isinstance(perm, (list, tuple)) and all(isinstance(p, (list, tuple)) and len(p) == 2 for p in perm)","typeGuard":"def valid_ppermute_perm(perm):\n    return isinstance(perm, (list, tuple)) and all(\n        isinstance(p, (list, tuple)) and len(p) == 2 for p in perm)","tryCatchPattern":null,"preventionTips":["Normalize perms: perm = [tuple(map(int, p)) for p in perm]","Use pshuffle for flat permutations"],"tags":["jax","ppermute","typeerror","collectives"],"backgroundTag":"wrong-argument-type","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}