pypa/pip · error · TypeError

typecode must have int type.

Error message

typecode must have int type.

What it means

Raised by msgpack's pure-Python Packer.pack_ext_type when the typecode argument is not an instance of int. The msgpack extension type format encodes the type code as a single signed or unsigned byte, so it must be an integer. Note that ExtType.__new__ also validates this at construction time (ext.py:10-11), so this check in pack_ext_type is a secondary guard for callers who construct raw ext data.

Source

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

            raise ValueError
        self._pack_array_header(n)
        if self._autoreset:
            ret = self._buffer.getvalue()
            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:

View on GitHub (pinned to f399c37189)

Solutions

  1. Ensure typecode is an int: coerce with int(typecode) before calling pack_ext_type.
  2. Validate the typecode type at the source where it is configured.
  3. Use the ExtType namedtuple constructor which validates at creation: ExtType(code, data).

Example fix

# before
packer.pack_ext_type('1', b'data')  # string typecode — raises

# after
packer.pack_ext_type(int('1'), b'data')
Defensive patterns

Strategy: type-guard

Validate before calling

def validate_ext_typecode(typecode) -> int:
    if not isinstance(typecode, int):
        raise TypeError(f'typecode must be int, got {type(typecode).__name__}')
    return typecode

Type guard

def is_int_typecode(typecode) -> bool:
    return isinstance(typecode, int) and not isinstance(typecode, bool)

Try / catch

try:
    packer.pack_ext_type(typecode, data)
except TypeError as e:
    if 'must have int type' in str(e):
        packer.pack_ext_type(int(typecode), data)
    else:
        raise

Prevention

When it happens

Trigger: Calling packer.pack_ext_type(typecode, data) where typecode is a string, float, or any non-int value. Also possible if constructing the ext payload manually bypassing ExtType's constructor.

Common situations: Passing a string typecode from config; float typecode from a computation; dynamic typecode resolution that doesn't coerce to int.

Related errors


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