Skip to content

How to Resolve Python "AttributeError: 'str' object has no attribute" Error

Fix the Python AttributeError when trying to call string methods like .items(), .write(), or .contains() by identifying type mismatches and using correct string operations or parsing.

The AttributeError: 'str' object has no attribute '...' is a common error indicating a type mismatch in your Python code. You're attempting to use a method or access an attribute that exists for a different data type (like a dictionary, list, or file object) on a variable that currently holds a string (str).

This guide explains the common causes of this error and provides specific solutions for frequent cases like items, keys, contains, write, read, and remove.

Understanding the Error: Type Mismatch on Strings

Python strings (str) have a specific set of built-in methods (like .upper(), .split(), .startswith()) and attributes. This error occurs when you try to call a method or access an attribute on a string variable that is not defined for strings. For example, .append() belongs to lists, .items() belongs to dictionaries, and .write() belongs to file objects.

my_variable = "this is a string"

try:
    my_variable.append(" more text")
except AttributeError as e:
    print(e)

Common Causes

Accidental String Assignment

A variable you expected to hold a different type (like a list, dict, or file handle) was mistakenly assigned a string value somewhere earlier in the code.

my_data = {'key': 'value'}  # Expected a dictionary
my_data = "some string"     # ⚠️ Accidental reassignment
try:
    print(my_data.items())
except AttributeError as e:
    print(e)

Incorrect Object Usage (e.g., File Handles, JSON)

You might be calling a method on the wrong object, like calling .write() on a filename (string) instead of the opened file object, or trying dictionary methods on a raw JSON string.

Misunderstanding Method Availability (e.g., contains)

You might assume a method exists for strings when it doesn't (like .contains()). Python often uses operators (in) or different methods (.find(), .index()) for such functionality.

Misspelled Method Names

Method names are case-sensitive. Typing .Lower() instead of .lower() will cause an AttributeError.

Debugging Steps

Check the Variable's Type

Verify the type of the variable immediately before the line causing the error.

variable_causing_error = "some value"

print(f"Type right before error: {type(variable_causing_error)}")

try:
    variable_causing_error.non_existent_method()
except AttributeError as e:
    print(f"Error: {e}")

Inspect Available Attributes (dir())

Use dir() to see exactly which attributes and methods are actually available for the object (which you've identified as a string).

my_string = "hello"

print(dir(my_string))

Output will show valid string methods like:

['capitalize', 'casefold', ..., 'find', 'format', ..., 'join', 'lower', ..., 'split', 'startswith', 'strip', 'upper', ...]
  • Notice the absence of methods like 'items', 'write', 'append', 'remove', 'contains', etc.
  • If the method you're trying to call isn't in the dir() list for a string, that confirms the cause of the AttributeError.

General Solutions

Correct the Variable Assignment/Usage

Trace back in your code to find where the variable was incorrectly assigned a string value and fix the logic. Ensure you are calling methods on the correct object (e.g., the file handle, not the filename).

Use the Correct Method/Operator for Strings

If you're trying to perform an action on a string, use the appropriate string method or operator (e.g., use the in operator instead of .contains(), use .replace() instead of .remove()).

Convert the String (If Applicable, e.g., JSON)

If the string represents data in another format (like JSON), parse it into the correct Python type before trying to use methods specific to that type.

Specific Error Examples and Solutions

AttributeError: 'str' object has no attribute 'items' (or 'keys')

  • Cause: Calling dictionary methods (.items(), .keys()) on a string. This often happens with JSON strings that haven't been parsed.
  • Error Scenario:
    json_string = '{"id": 1, "value": "data"}'
    print(type(json_string)) # Output: <class 'str'>
    try:
        print(json_string.items())
    except AttributeError as e:
        print(e)
  • Solution: If it's a JSON string, parse it into a Python dictionary using json.loads() first. If it's meant to be a dictionary, fix the assignment.
    import json
    json_string = '{"id": 1, "value": "data"}'
    my_dict = json.loads(json_string)
    print(type(my_dict)) # Output: <class 'dict'>
    print(my_dict.items()) # Output: dict_items([('id', 1), ('value', 'data')])
    print(my_dict.keys()) # Output: dict_keys(['id', 'value'])
  • Note on requests: When passing headers to requests.post or requests.get, provide a Python dictionary directly, not a JSON string.

AttributeError: 'str' object has no attribute 'contains'

  • Cause: Trying to call a non-existent .contains() method on a string.
  • Error Scenario:
    message = "hello world"
    try:
        if message.contains("world"):
            print("Found it")
    except AttributeError as e:
        print(e)
  • Solution: Use the in operator for substring checks.
    message = "hello world"
    substring = "world"
    if substring in message:
        print(f"'{substring}' found in '{message}'") # Output: 'world' found in 'hello world'
    
    if substring.lower() in message.lower():
         print("Found it (case-insensitive)")

AttributeError: 'str' object has no attribute 'write'

  • Cause: Calling the file method .write() on a string variable (often the filename) instead of the opened file object/handle.
  • Error Scenario:
    filename = "output.txt"
    try:
        with open(filename, 'w', encoding='utf-8') as f:
             filename.write("Some data\n")
    except AttributeError as e:
        print(e)
  • Solution: Call .write() on the file object returned by open() (commonly named f or file in with statements).
    filename = "output.txt"
    try:
        with open(filename, 'w', encoding='utf-8') as my_file:
             my_file.write("Some data\n")
             my_file.write("More data\n")
        print(f"Data written to {filename}")
    except Exception as e:
        print(f"An error occurred: {e}")

AttributeError: 'str' object has no attribute 'read'

  • Cause: Calling the file method .read() on a string (like a filename), or mistakenly using json.load() (for files) on a JSON string instead of json.loads() (for strings).
  • Error Scenario 1 (File Handling):
    filename = "input.txt"
    try:
        with open(filename, 'r', encoding='utf-8') as f:
             data = filename.read()
    except AttributeError as e:
        print(f"File Error: {e}")
  • Error Scenario 2 (JSON):
    import json
    json_string = '{"value": 10}'
    try:
        data = json.load(json_string)
    except AttributeError as e:
        print(f"JSON Error: {e}")
  • Solution (File Handling): Call .read() on the file object.
    filename = "input.txt"
    try:
        with open(filename, 'r', encoding='utf-8') as f:
             data = f.read()
             print("File content read.")
    except FileNotFoundError:
         print(f"Error: File '{filename}' not found.")
    except Exception as e:
         print(f"An error occurred: {e}")
  • Solution (JSON): Use json.loads() (with 's') for strings.
    import json
    json_string = '{"value": 10}'
    data = json.loads(json_string)
    print(f"Parsed JSON: {data}") # Output: Parsed JSON: {'value': 10}

AttributeError: 'str' object has no attribute 'remove'

  • Cause: Trying to call the list method .remove() on a string. Strings are immutable and don't have a .remove() method.
  • Error Scenario:
    my_string = "abc-def-ghi"
    try:
        my_string.remove("-def")
    except AttributeError as e:
        print(e)
    
    my_list = ["apple", "banana", "cherry"]
    try:
         my_list[1].remove("a")
    except AttributeError as e:
         print(f"List element error: {e}")
  • Solution: To "remove" a substring from a string, use the .replace() method, replacing the target substring with an empty string. If working with a list, call .remove() on the list itself, not on its string elements.
    my_string = "abc-def-ghi"
    new_string = my_string.replace("-def", "")
    print(new_string) # Output: abc-ghi
    
    my_list = ["apple", "banana", "cherry"]
    my_list.remove("banana")
    print(my_list) # Output: ['apple', 'cherry']

Conclusion

The AttributeError: 'str' object has no attribute '...' error is a signal to check your variable types. It usually means a variable holds a string when you expected something else (like a list, dictionary, or file object), or you're trying to use a method name that doesn't exist for strings.

To fix it:

  1. Verify the variable's type using print(type(variable)).
  2. Trace the variable assignment to correct any mistakes.
  3. Ensure you're calling methods on the correct object (e.g., file handle vs. filename).
  4. Use the appropriate methods or operators designed for strings (like in or .replace()).
  5. Parse strings containing structured data (like JSON) into the proper Python objects before processing.
Navigation