jax-ml/jax · error · TypeError

Expected an input array of integer or boolean data type

Error message

Expected an input array of integer or boolean data type

What it means

Raised by jnp.packbits when the input's dtype is neither integer nor boolean — packbits packs each element into one bit, which is only meaningful for integral/boolean data.

Source

Thrown at jax/_src/numpy/lax_numpy.py:8695

    For a multi-dimensional input, bits may be packed along a specified axis:

    >>> a = jnp.array([[1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0],
    ...                [0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1]])
    >>> vals = jnp.packbits(a, axis=1)
    >>> vals
    Array([[212, 150],
           [ 69, 207]], dtype=uint8)

    The inverse of ``packbits`` is provided by :func:`~jax.numpy.unpackbits`:

    >>> jnp.unpackbits(vals, axis=1)
    Array([[1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0],
           [0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1]], dtype=uint8)
  """
  arr = util.ensure_arraylike("packbits", a)
  if not (issubdtype(arr.dtype, np.integer) or issubdtype(arr.dtype, np.bool_)):
    raise TypeError('Expected an input array of integer or boolean data type')
  if bitorder not in ['little', 'big']:
    raise ValueError("'order' must be either 'little' or 'big'")
  arr = lax.ne(arr, lax._const(arr, 0)).astype('uint8')
  bits = arange(8, dtype='uint8')
  if bitorder == 'big':
    bits = bits[::-1]
  if axis is None:
    arr = ravel(arr)
    axis = 0
  arr = swapaxes(arr, axis, -1)

  remainder = arr.shape[-1] % 8
  if remainder:
    arr = lax.pad(arr, np.uint8(0),
                  (arr.ndim - 1) * [(0, 0, 0)] + [(0, 8 - remainder, 0)])

  arr = arr.reshape(arr.shape[:-1] + (arr.shape[-1] // 8, 8))
  bits = expand_dims(bits, tuple(range(arr.ndim - 1)))

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Convert to bool first: jnp.packbits(a.astype(bool)) — nonzero/true packs as 1
  2. If floats encode bit values, threshold explicitly: (a > 0).astype(bool)
  3. Verify the pipeline stage: packbits is for bit-packing, not general compression

Example fix

// before
jnp.packbits(scores)  # float32
// after
jnp.packbits(scores > 0.5)
Defensive patterns

Strategy: type-guard

Validate before calling

arr = jnp.asarray(a)
if not (jnp.issubdtype(arr.dtype, jnp.integer) or arr.dtype == jnp.bool_):
    arr = arr.astype(bool)

Type guard

def packbits_compatible(a):
    d = jnp.asarray(a).dtype
    return jnp.issubdtype(d, jnp.integer) or d == jnp.bool_

Prevention

When it happens

Trigger: jnp.packbits(float_array); input from a computation that yields float32/float64; passing strings or complex arrays.

Common situations: Packing boolean results of comparisons that were later converted to float; feeding normalized/standardized numeric features into packbits by mistake; NumPy code where uint8 was implicit.

Related errors


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