{"record":{"id":"9aa4b0f5dab8db10","repo":"pypa/pip","slug":"typecode-must-have-int-type","errorCode":null,"errorMessage":"typecode must have int type.","messagePattern":"typecode must have int type\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/msgpack/fallback.py","lineNumber":844,"sourceCode":"            raise ValueError\n        self._pack_array_header(n)\n        if self._autoreset:\n            ret = self._buffer.getvalue()\n            self._buffer = BytesIO()\n            return ret\n\n    def pack_map_header(self, n):\n        if n >= 2**32:\n            raise ValueError\n        self._pack_map_header(n)\n        if self._autoreset:\n            ret = self._buffer.getvalue()\n            self._buffer = BytesIO()\n            return ret\n\n    def pack_ext_type(self, typecode, data):\n        if not isinstance(typecode, int):\n            raise TypeError(\"typecode must have int type.\")\n        if not 0 <= typecode <= 127:\n            raise ValueError(\"typecode should be 0-127\")\n        if not isinstance(data, bytes):\n            raise TypeError(\"data must have bytes type\")\n        L = len(data)\n        if L > 0xFFFFFFFF:\n            raise ValueError(\"Too large data\")\n        if L == 1:\n            self._buffer.write(b\"\\xd4\")\n        elif L == 2:\n            self._buffer.write(b\"\\xd5\")\n        elif L == 4:\n            self._buffer.write(b\"\\xd6\")\n        elif L == 8:\n            self._buffer.write(b\"\\xd7\")\n        elif L == 16:\n            self._buffer.write(b\"\\xd8\")\n        elif L <= 0xFF:","sourceCodeStart":826,"sourceCodeEnd":862,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/msgpack/fallback.py#L826-L862","documentation":"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.","triggerScenarios":"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.","commonSituations":"Passing a string typecode from config; float typecode from a computation; dynamic typecode resolution that doesn't coerce to int.","solutions":["Ensure typecode is an int: coerce with int(typecode) before calling pack_ext_type.","Validate the typecode type at the source where it is configured.","Use the ExtType namedtuple constructor which validates at creation: ExtType(code, data)."],"exampleFix":"# before\npacker.pack_ext_type('1', b'data')  # string typecode — raises\n\n# after\npacker.pack_ext_type(int('1'), b'data')","handlingStrategy":"type-guard","validationCode":"def validate_ext_typecode(typecode) -> int:\n    if not isinstance(typecode, int):\n        raise TypeError(f'typecode must be int, got {type(typecode).__name__}')\n    return typecode","typeGuard":"def is_int_typecode(typecode) -> bool:\n    return isinstance(typecode, int) and not isinstance(typecode, bool)","tryCatchPattern":"try:\n    packer.pack_ext_type(typecode, data)\nexcept TypeError as e:\n    if 'must have int type' in str(e):\n        packer.pack_ext_type(int(typecode), data)\n    else:\n        raise","preventionTips":["Coerce typecode to int at the source.","Use typed config (int, not str) for extension type codes.","Prefer ExtType namedtuple which validates at construction."],"tags":["msgpack","ext-type","type-error","validation"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}