Skip to content

How to Resolve Python Error "TypeError: isinstance() arg 2 must be a type, tuple of types, or a union"

Fix the Python TypeError in isinstance() by ensuring the second argument is a valid type, tuple of types, or union, common causes include passing lists or shadowing built-in type names.

The isinstance() function is a fundamental tool in Python for checking an object's type. The TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union arises when the second argument provided to isinstance() is not what Python expects for type checking. Usually, this means you've passed a list or another non-type object instead of a single type object (like str, int, list) or a tuple containing type objects.

This guide explains the correct usage of isinstance()'s second argument and provides solutions for the common mistakes that lead to this error.

Understanding the Error: isinstance() Syntax

The isinstance() function checks if an object is an instance of a particular class or a subclass thereof. Its syntax is:

isinstance(object, classinfo)

  • object: The object whose type you want to check.
  • classinfo: This is where the error occurs. This argument must be either:
    • A single type object (e.g., int, str, list, dict, float, bool, a custom class name).
    • A tuple containing two or more type objects (e.g., (str, int), (list, tuple, set)). The function returns True if the object is an instance of any of the types in the tuple.

The TypeError occurs because the value passed as the classinfo argument doesn't fit these requirements – most commonly, it's a list instance or another non-type object.

Cause 1: Passing a List Instead of a Tuple for Multiple Types

When checking if an object belongs to one of several possible types, you must provide those types within a tuple, not a list.

Error Scenario

value = 123
allowed_types_list = [str, int, float] # This is a LIST of types

print(f"Type of allowed_types_list: {type(allowed_types_list)}") # Output: <class 'list'>

try:
    if isinstance(value, allowed_types_list):
        print("Value is of an allowed type.")
except TypeError as e:
    print(e)

Output:

Type of allowed_types_list: <class 'list'>
isinstance() arg 2 must be a type or tuple of types

Solution: Use a Tuple of Types

Provide the multiple types within a tuple () directly, or convert your list of types to a tuple using tuple().

value = 123
allowed_types_list = [str, int, float]

allowed_types_tuple = tuple(allowed_types_list)
print(f"Type of allowed_types_tuple: {type(allowed_types_tuple)}") # Output: <class 'tuple'>
if isinstance(value, allowed_types_tuple):
    print(f"Value {value} is an instance of one of {allowed_types_tuple} (using tuple conversion).") # This is executed
else:
     print(f"Value {value} is not an instance (using tuple conversion).")

if isinstance(value, (str, int, float)): # Pass tuple literal directly
    print(f"Value {value} is an instance of one of (str, int, float) (using tuple literal).") # This is executed
else:
    print(f"Value {value} is not an instance (using tuple literal).")

another_value = "hello"
if isinstance(another_value, (str, int, float)):
     print(f"Value '{another_value}' is an instance of one of (str, int, float).") # This is executed

Output:

Type of allowed_types_tuple: <class 'tuple'>
Value 123 is an instance of one of (<class 'str'>, <class 'int'>, <class 'float'>) (using tuple conversion).
Value 123 is an instance of one of (str, int, float) (using tuple literal).
Value 'hello' is an instance of one of (str, int, float).

Using a tuple literal (type1, type2, ...) directly is usually the clearest approach.

Cause 2: Shadowing Built-in Type Names

This error can also occur if you unintentionally assign a value (especially a list or other non-type object) to a variable that has the same name as a built-in type (like list, str, dict, int). This is called "shadowing."

Error Scenario

list = ["apple", "banana"] # 'list' now refers to this specific list instance

my_data = [1, 2, 3]

print(f"Value of shadowed 'list': {list}")  

print(f"Type of shadowed 'list': {type(list)}") 

try:
    if isinstance(my_data, list):
        print("my_data is a list.")
except TypeError as e:
    print(e)

Output:

Value of shadowed 'list': ['apple', 'banana']
Type of shadowed 'list': <class 'list'>
isinstance() arg 2 must be a type or tuple of types

Because the name list was reassigned, it no longer refers to the built-in list type object that isinstance() expects. It refers to the actual list instance ["apple", "banana"].

The best and cleanest solution is to avoid shadowing built-in type names. Rename your variable to something descriptive that doesn't conflict.

my_string_list = ["apple", "banana"] # Use a different name

my_data = [1, 2, 3]

if isinstance(my_data, list):
    print("my_data is a list (after renaming variable).") # This is executed
else:
    print("my_data is not a list (after renaming variable).")

Solution 2: Use type() to Get the Type (Workaround)

If renaming the variable is absolutely not feasible (which is rare and usually indicates a need for code refactoring), you can get the type of the shadowing variable using type() and pass that to isinstance().

list = ["apple", "banana"] # 'list' is the instance
my_data = [1, 2, 3]

list_type_obj = type(list) # This correctly gets <class 'list'>
print(f"Type obtained via type(list): {list_type_obj}")

if isinstance(my_data, list_type_obj):
    print("my_data is a list (using type() workaround).")    # This is executed

if isinstance(my_data, type([])): # type([]) also returns <class 'list'>
     print("my_data is a list (using type([]) workaround).") # This is executed

Output:

Type obtained via type(list): <class 'list'>
my_data is a list (using type() workaround).
my_data is a list (using type([]) workaround).

Debugging the Error

When isinstance() raises this TypeError:

  1. Focus on the second argument passed to isinstance().
  2. Print its value and type just before the isinstance() call:
    print(f"DEBUG: Arg 2 value: {repr(second_argument)}")
    print(f"DEBUG: Arg 2 type: {type(second_argument)}")
  3. If the type is list: You need to convert it to a tuple (tuple(second_argument)) or rewrite it as a tuple literal (type1, type2).
  4. If the type is NOT type or tuple: You've likely shadowed a built-in type name with a variable. Find the variable assignment and rename the variable.

Conclusion

The TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union occurs when the second argument provided to isinstance() is invalid for type checking.

The main solutions are:

  1. When checking against multiple types, provide them within a tuple (type1, type2, ...), not a list [type1, type2, ...].
  2. Avoid shadowing built-in type names (like list, str, dict, int) with your variable names. Rename conflicting variables (e.g., use my_list instead of list).

By ensuring the second argument to isinstance() is always a type object or a tuple of type objects, you can effectively use it for robust type checking in Python.

Navigation