Skip to main content

How to Resolve Python "AttributeError: 'bool' object has no attribute '...'"

The AttributeError: 'bool' object has no attribute '...' is a Python error indicating a fundamental type mismatch. It occurs when you attempt to access an attribute or call a method on a variable that holds a boolean value (True or False), but that attribute or method doesn't exist for booleans. Booleans are simple types representing truth values and lack the methods associated with more complex objects like strings, lists, dictionaries, or custom classes.

This guide explains the common scenarios leading to this error and provides clear steps to diagnose and fix the underlying issue in your code.

Understanding Python Booleans (True and False)

In Python, True and False are the two constant objects of the bool type. They are used to represent truth values in logical operations and conditional statements. While they are technically subclasses of integers (where True acts like 1 and False like 0 in arithmetic), they are primarily used for logic and do not possess the wide range of attributes and methods found on other types like:

  • String methods (.upper(), .split(), etc.)
  • List methods (.append(), .sort(), etc.)
  • Dictionary methods (.items(), .keys(), etc.)
  • Attributes defined in your custom classes (.name, .value, etc.)

The Cause: Type Mismatch

This AttributeError occurs because your code tries to perform an operation (like my_variable.some_attribute or my_variable.some_method()) on a variable, but at that moment, my_variable holds either True or False. Python looks for some_attribute or some_method on the boolean object, doesn't find it, and raises the error. The core issue is that the variable contains a different type than your code expects at that point.

is_active = True # A boolean variable

print(type(is_active)) # Output: <class 'bool'>

try:
# ⛔️ AttributeError: 'bool' object has no attribute 'upper'
# Booleans do not have an .upper() method like strings do.
status_upper = is_active.upper()
print(status_upper)
except AttributeError as e:
print(e)

Common Scenarios Leading to the Error

The variable holding the boolean value usually gets assigned unexpectedly. Here are common ways this happens:

Function Returning a Boolean Instead of an Object

A function you expected to return an object (like a user instance, a configuration dictionary, etc.) might return True or False under certain conditions (e.g., to indicate success/failure, existence/non-existence).

class User:
def __init__(self, name):
self.name = name

def find_user(user_id):
if user_id == 1:
return User("Alice")
else:
# ⚠️ Function returns False if user not found
return False

# --- Scenario 1: User found ---
user_obj = find_user(1)
print(f"User 1 Type: {type(user_obj)}") # <class '__main__.User'>
print(f"User 1 Name: {user_obj.name}") # Works: Alice

# --- Scenario 2: User not found ---
user_obj_or_bool = find_user(2)
print(f"User 2 Type: {type(user_obj_or_bool)}") # Output: <class 'bool'>

try:
# ⛔️ AttributeError: 'bool' object has no attribute 'name'
# user_obj_or_bool is False here
print(f"User 2 Name: {user_obj_or_bool.name}")
except AttributeError as e:
print(e)

Variable Assigned the Result of a Comparison

Comparisons (==, !=, >, <, >=, <=) and logical operations (in, not in, is, is not) always evaluate to True or False. If you assign this result to a variable intended for something else, you'll get the error later.

items = [10, 20, 30]
threshold = 15

# Check if the list length is greater than the threshold
# The result of the comparison (True) is stored in 'data_status'
data_status = len(items) > threshold
print(f"Data Status: {data_status}, Type: {type(data_status)}") # Output: Data Status: False, Type: <class 'bool'>

try:
# ⛔️ AttributeError: 'bool' object has no attribute 'append'
# Trying to use a list method on the boolean result
data_status.append(40)
except AttributeError as e:
print(e)

Accidental Reassignment to a Boolean

A variable might initially hold the correct object type, but later in the code (perhaps inside a loop or conditional block), it gets mistakenly reassigned to True or False.

class Config:
def __init__(self, settings):
self.settings = settings

# Initialize correctly
app_config = Config({"theme": "dark", "font_size": 12})
print(f"Initial type: {type(app_config)}") # Output: Initial type: <class '__main__.Config'>

# ... some code ...

# ⚠️ Accidental reassignment (e.g., inside an unrelated check)
config_is_valid = True # Some flag
app_config = config_is_valid # Mistakenly overwrites the Config object

print(f"Type after reassignment: {type(app_config)}") # Output: Type after reassignment: <class 'bool'>

# ... later ...
try:
# ⛔️ AttributeError: 'bool' object has no attribute 'settings'
# app_config is now True, not the Config object
theme = app_config.settings['theme']
print(f"Theme: {theme}")
except AttributeError as e:
print(e)
note

This is a very common cause, often harder to spot in larger codebases.

Debugging Steps

Check the Variable's Type

Right before the line causing the AttributeError, print the type of the variable:

print(f"DEBUG: Type of my_variable is {type(my_variable)}")
# >> The line causing the error, e.g., value = my_variable.attribute

If the output is <class 'bool'>, you've confirmed the immediate cause.

Trace the Variable's Assignment

Now, you need to find out why it's a boolean.

  • Work backward from the error line.
  • Where was the variable last assigned a value?
  • Was it the return value of a function? Check what that function returns in all possible cases.
  • Was it the result of a comparison?
  • Was it reassigned inside a loop or if statement?
  • Use print statements or a debugger to inspect the variable's value at different points before the error.

Solutions

Primary Solution: Fix the Incorrect Assignment/Logic

The fundamental solution is to find the source of the unexpected boolean value (as identified in the debugging step) and correct the logic.

  • If a function returns a boolean instead of an object on failure, adjust the calling code to handle the boolean case explicitly (e.g., if user_object: print(user_object.name) else: print("User not found")). Don't try to access attributes on the boolean False.
  • If a variable was reassigned by mistake, remove or correct the reassignment so it retains the intended object type.
  • If the variable holds the result of a comparison, use a different variable name for the comparison result and keep the original variable holding the object/data you need.
# --- Corrected Reassignment Example ---
class Config:
def __init__(self, settings):
self.settings = settings

app_config = Config({"theme": "dark", "font_size": 12})
print(f"Initial type: {type(app_config)}")

# ... some code ...

# ✅ Use a separate variable for the boolean check
config_is_valid = True # Some flag
# DO NOT REASSIGN app_config here

# ... later ...
# ✅ app_config still holds the Config object
theme = app_config.settings['theme']
print(f"Theme: {theme}") # Output: Theme: dark

Defensive Check: Using hasattr() (Use with Caution)

You can prevent the crash by checking if the attribute exists before accessing it using hasattr(object, name).

maybe_bool = False # Could be a boolean or an object

if hasattr(maybe_bool, 'some_attribute'):
# This block only runs if maybe_bool has 'some_attribute'
print(maybe_bool.some_attribute)
else:
# Handle the case where it's a boolean or lacks the attribute
print(f"'{maybe_bool}' does not have 'some_attribute' (Type: {type(maybe_bool)})")
# Output: 'False' does not have 'some_attribute' (Type: <class 'bool'>)
warning

While hasattr prevents the AttributeError, it does not fix the underlying problem that your variable holds an unexpected type (bool). It masks the logic error. Use this primarily when dealing with intentional polymorphism (where a variable could legitimately hold different types with different capabilities), not as a workaround for unexpected boolean assignments.

Conclusion

The AttributeError: 'bool' object has no attribute '...' arises from trying to treat a boolean value (True or False) as if it were a more complex object with specific attributes or methods. The root cause is almost always that the variable you're using contains a boolean when you expected it to contain something else (an object, string, list, etc.).

The key to solving this is:

  1. Identify that the variable holds a bool using type().
  2. Trace back to find where the variable was incorrectly assigned the boolean value (function return, comparison result, accidental reassignment).
  3. Correct the assignment logic so the variable holds the expected type when the attribute/method access occurs.

Using hasattr() can prevent the crash but should be used cautiously as it doesn't address the core logical issue.