pypa/pip · error · TypeError

data must have bytes type

Error message

data must have bytes type

What it means

Raised by msgpack's pure-Python Packer.pack_ext_type when the data argument is not a bytes instance (bytearray or memoryview are also rejected here — it checks isinstance(data, bytes) strictly). The ext type payload must be raw bytes for the binary wire format. Note ExtType.__new__ in ext.py:12 enforces the same constraint.

Source

Thrown at src/pip/_vendor/msgpack/fallback.py:848

            self._buffer = BytesIO()
            return ret

    def pack_map_header(self, n):
        if n >= 2**32:
            raise ValueError
        self._pack_map_header(n)
        if self._autoreset:
            ret = self._buffer.getvalue()
            self._buffer = BytesIO()
            return ret

    def pack_ext_type(self, typecode, data):
        if not isinstance(typecode, int):
            raise TypeError("typecode must have int type.")
        if not 0 <= typecode <= 127:
            raise ValueError("typecode should be 0-127")
        if not isinstance(data, bytes):
            raise TypeError("data must have bytes type")
        L = len(data)
        if L > 0xFFFFFFFF:
            raise ValueError("Too large data")
        if L == 1:
            self._buffer.write(b"\xd4")
        elif L == 2:
            self._buffer.write(b"\xd5")
        elif L == 4:
            self._buffer.write(b"\xd6")
        elif L == 8:
            self._buffer.write(b"\xd7")
        elif L == 16:
            self._buffer.write(b"\xd8")
        elif L <= 0xFF:
            self._buffer.write(b"\xc7" + struct.pack("B", L))
        elif L <= 0xFFFF:
            self._buffer.write(b"\xc8" + struct.pack(">H", L))
        else:

View on GitHub (pinned to f399c37189)

Solutions

  1. Convert data to bytes before calling pack_ext_type: data = bytes(data) or data = data.encode('utf-8').
  2. If using bytearray, convert with bytes(bytearray_obj).
  3. If using memoryview, call .tobytes() first.
  4. Pre-serialize structured data to bytes before wrapping in an ext type.

Example fix

# before
packer.pack_ext_type(1, 'hello')  # str — raises

# after
packer.pack_ext_type(1, b'hello')  # bytes
Defensive patterns

Strategy: type-guard

Validate before calling

def ensure_bytes(data) -> bytes:
    if isinstance(data, str):
        return data.encode('utf-8')
    if isinstance(data, (bytearray, memoryview)):
        return bytes(data)
    if not isinstance(data, bytes):
        raise TypeError(f'data must be bytes, got {type(data).__name__}')
    return data

Type guard

def is_bytes_data(data) -> bool:
    return isinstance(data, bytes)

Try / catch

try:
    packer.pack_ext_type(code, data)
except TypeError as e:
    if 'must have bytes type' in str(e):
        data = bytes(data) if not isinstance(data, str) else data.encode()
        packer.pack_ext_type(code, data)
    else:
        raise

Prevention

When it happens

Trigger: Calling packer.pack_ext_type(1, 'string data') or packer.pack_ext_type(1, bytearray(b'x')) or packer.pack_ext_type(1, [1,2,3]). Any non-bytes data type triggers it.

Common situations: Passing a string instead of bytes; using bytearray (which pack_ext_type rejects, though _pack accepts bytearray for bin types); list/int payload that hasn't been pre-serialized.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/3ce07b75e39d9205. Report an issue: GitHub.