jax-ml/jax · error · TypeError

transpose permutation must be a tuple/list/ndarray, got {typ

Error message

transpose permutation must be a tuple/list/ndarray, got {type(permutation)}.

What it means

BCOO transpose (and reshape, which uses transpose internally) requires the permutation as a tuple, list, or numpy array. Passing another type (int, jax array, generator) raises TypeError.

Source

Thrown at jax/experimental/sparse/bcoo.py:537

  Returns:
    A BCOO-format array.
  """
  buffers = _bcoo_transpose(mat.data, mat.indices, permutation=permutation, spinfo=mat._info)
  out_shape = tuple(mat.shape[p] for p in permutation)
  return BCOO(buffers, shape=out_shape, unique_indices=mat.unique_indices)

def _bcoo_transpose(data: Array, indices: Array, *,
                    permutation: Sequence[int], spinfo: SparseInfo) -> tuple[Array, Array]:
  permutation = tuple(permutation)
  if permutation == tuple(range(len(spinfo.shape))):
    return data, indices
  else:
    return bcoo_transpose_p.bind(data, indices, permutation=permutation,
                                 spinfo=spinfo)

def _validate_permutation(data, indices, permutation, shape):
  if not isinstance(permutation, (tuple, list, np.ndarray)):
    raise TypeError(f"transpose permutation must be a tuple/list/ndarray, got {type(permutation)}.")
  if tuple(sorted(permutation)) != tuple(range(len(shape))):
    raise TypeError("transpose permutation isn't a permutation of operand dimensions, "
                    f"got permutation {permutation} for shape {shape}.")
  n_batch, n_sparse, n_dense, _ = _validate_bcoo(data, indices, shape)
  batch_perm = permutation[:n_batch]
  sparse_perm = [p - n_batch for p in permutation[n_batch: n_batch + n_sparse]]
  dense_perm = [p - n_sparse - n_batch for p in permutation[n_batch + n_sparse:]]
  if n_batch and tuple(sorted(batch_perm)) != tuple(range(n_batch)):
    raise NotImplementedError("transpose permutation cannot permute batch axes with non-batch axes; "
                              f"got permutation {permutation}, with {n_batch=}.")
  if n_dense and tuple(sorted(dense_perm)) != tuple(range(n_dense)):
    raise NotImplementedError("transpose permutation cannot permute dense axes with non-dense axes; "
                              f"got permutation {permutation}, with {n_dense=}.")
  return batch_perm, sparse_perm, dense_perm

@bcoo_transpose_p.def_impl
def _bcoo_transpose_impl(data, indices, *, permutation: Sequence[int], spinfo: SparseInfo):
  batch_perm, sparse_perm, dense_perm = _validate_permutation(data, indices, permutation, spinfo.shape)

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Convert: perm = tuple(perm) (or np.asarray) before calling transpose
  2. Avoid passing jax arrays as static metadata to sparse ops

Example fix

// before
perm = jnp.array([1, 0])
out = bcoo.transpose(perm)
// after
perm = (1, 0)
out = bcoo.transpose(perm)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(perm, (tuple, list)):
    perm = tuple(perm.tolist() if hasattr(perm, 'tolist') else perm)

Type guard

def is_valid_perm_type(p) -> bool:
    return isinstance(p, (tuple, list)) or type(p).__module__ == 'numpy'

Prevention

When it happens

Trigger: Calling bcoo.transpose(perm) or sparsified jnp.transpose with perm given as a JAX DeviceArray, an int, or another iterable type.

Common situations: Passing a jnp.array permutation computed under jit instead of tuple(perm); forgetting to unpack a single int as a tuple.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/c02e5c8bb3cfdc62. Report an issue: GitHub.