{"record":{"id":"add41df8ee9cbb0b","repo":"jax-ml/jax","slug":"expected-an-input-array-of-unsigned-byte-data-type","errorCode":null,"errorMessage":"Expected an input array of unsigned byte data type","messagePattern":"Expected an input array of unsigned byte data type","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/numpy/lax_numpy.py","lineNumber":8789,"sourceCode":"           [ 49]], dtype=uint8)\n\n    The ``count`` keyword lets ``unpackbits`` serve as an inverse of ``packbits``\n    in cases where not all bits are present:\n\n    >>> bits = jnp.array([1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1])  # 11 bits\n    >>> vals = jnp.packbits(bits)\n    >>> vals\n    Array([219,  96], dtype=uint8)\n    >>> jnp.unpackbits(vals)  # 16 zero-padded bits\n    Array([1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0], dtype=uint8)\n    >>> jnp.unpackbits(vals, count=11)  # specify 11 output bits\n    Array([1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1], dtype=uint8)\n    >>> jnp.unpackbits(vals, count=-5)  # specify 5 bits to be trimmed\n    Array([1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1], dtype=uint8)\n  \"\"\"\n  arr = util.ensure_arraylike(\"unpackbits\", a)\n  if arr.dtype != np.uint8:\n    raise TypeError(\"Expected an input array of unsigned byte data type\")\n  if bitorder not in ['little', 'big']:\n    raise ValueError(\"'order' must be either 'little' or 'big'\")\n  bits = asarray(1) << arange(8, dtype='uint8')\n  if bitorder == 'big':\n    bits = bits[::-1]\n  if axis is None:\n    arr = ravel(arr)\n    axis = 0\n  arr = swapaxes(arr, axis, -1)\n  unpacked = ((arr[..., None] & expand_dims(bits, tuple(range(arr.ndim)))) > 0).astype('uint8')\n  unpacked = unpacked.reshape(unpacked.shape[:-2] + (-1,))\n  if count is not None:\n    if count > unpacked.shape[-1]:\n      unpacked = pad(unpacked, [(0, 0)] * (unpacked.ndim - 1) + [(0, count - unpacked.shape[-1])])\n    else:\n      unpacked = unpacked[..., :count]\n  return swapaxes(unpacked, axis, -1)\n","sourceCodeStart":8771,"sourceCodeEnd":8807,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/numpy/lax_numpy.py#L8771-L8807","documentation":"Raised by jnp.unpackbits when the input dtype is not uint8 — unpackbits expands each byte into 8 bits, so only unsigned 8-bit input is meaningful.","triggerScenarios":"jnp.unpackbits(int32_array), float arrays, or int8/uint16 data; results of arithmetic that promoted uint8 to int32.","commonSituations":"JAX type promotion: (uint8_array + 0) or comparisons yielding wider dtypes; data loaded as int64 indices then passed to unpackbits; porting NumPy code that relied on implicit casting.","solutions":["Cast explicitly: jnp.unpackbits(a.astype(np.uint8))","Avoid promotions upstream (use lax operations that preserve dtype, or ufuncs with dtype=uint8)","Confirm values fit in [0,255] before casting to avoid silent truncation"],"exampleFix":"// before\njnp.unpackbits(flags + 0)  # promoted to int32\n// after\njnp.unpackbits((flags + 0).astype(jnp.uint8))\n","handlingStrategy":"type-guard","validationCode":"arr = jnp.asarray(a)\nif arr.dtype != jnp.uint8: arr = arr.astype(jnp.uint8)","typeGuard":"def is_uint8(a):\n    return jnp.asarray(a).dtype == jnp.uint8","tryCatchPattern":null,"preventionTips":["Cast to uint8 explicitly before unpackbits","Watch JAX promotion widening uint8 to int32 in expressions","Validate value range before casting"],"tags":["jax","unpackbits","dtype-validation"],"backgroundTag":"dtype-validation-failed","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}