How to Resolve Python "TypeError: write() argument must be str, not ..."
The TypeError: write() argument must be str, not X (where X could be bytes, list, dict, tuple, None, etc.) is a common error when working with file I/O in Python. It occurs because the file.write() method, when a file is opened in text mode ('w', 'a', 'r+'), expects a string argument, but receives an object of a different, incompatible type.
This guide explains why this error happens and provides solutions for various types.
Understanding the Error: Text Mode vs. Binary Mode
Python's open() function has different modes:
- Text Mode (e.g.,
'w','r','a','r+'): Used for reading and writing text (strobjects). Data is automatically encoded/decoded using a specified (or default) encoding.write()expects astr. - Binary Mode (e.g.,
'wb','rb','ab','rb+'): Used for reading and writing raw binary data (bytesobjects). No encoding/decoding happens.write()expects abytes-like object.
The TypeError occurs when you open a file in text mode but try to write() something that isn't a string.
Handling TypeError: ... not bytes
Cause: Trying to write bytes to a file opened in text mode ('w').
# Error Example:
# with open('example.txt', 'w') as my_file:
# my_file.write(b'some bytes') # ⛔️ TypeError
Solution 1: Open in Binary Write Mode ('wb')
If you intend to write raw bytes, open the file in binary write mode:
with open('example.bin', 'wb') as my_file: # Use 'wb'
my_file.write(b'some bytes')
Solution 2: Decode Bytes to String (.decode())
If you want to write the text representation of the bytes, decode them first:
my_bytes = b'tutorialreference.com'
with open('example.txt', 'w', encoding='utf-8') as my_file:
my_file.write(my_bytes.decode('utf-8')) # Decode to string
Handling TypeError: ... not list
Cause: Trying to write a list object directly to a file opened in text mode.
# Error Example:
# my_list = ['Alice', 'Bob']
# with open('example.txt', 'w') as my_file:
# my_file.write(my_list) # ⛔️ TypeError
Solution 1: Join List Elements into a String (str.join())
Convert the list items into a single string using a chosen separator:
my_list = ['Alice', 'Bob', 'Carl']
with open('example.txt', 'w', encoding='utf-8') as my_file:
my_file.write(','.join(my_list)) # Join with commas
# File content: Alice,Bob,Carl
Ensure all list items are strings or convert them using map(str, my_list) or a generator expression before joining if they contain numbers or other types.
Solution 2: Convert List to String Representation (str())
Write the literal string representation of the list (including brackets and quotes):
my_list = ['Alice', 'Bob', 'Carl']
with open('example.txt', 'w', encoding='utf-8') as my_file:
my_file.write(str(my_list))
# File content: ['Alice', 'Bob', 'Carl']
Solution 3: Convert List to JSON String (json.dumps())
Serialize the list into a JSON array string:
import json
my_list = ['Alice', 'Bob', 'Carl']
with open('example.json', 'w', encoding='utf-8') as my_file:
my_file.write(json.dumps(my_list))
# File content: ["Alice", "Bob", "Carl"]
Handling TypeError: ... not dict
Cause: Trying to write a dict object directly to a file opened in text mode.
Solution 1: Convert Dictionary to String Representation (str())
Write the literal string representation of the dictionary:
my_dict = {'name': 'Alice', 'age': 30}
with open('example.txt', 'w', encoding='utf-8') as my_file:
my_file.write(str(my_dict))
File content:
{'name': 'Alice', 'age': 30}
Solution 2: Convert Dictionary to JSON String (json.dumps())
Serialize the dictionary into a JSON object string (recommended for structured data):
import json
my_dict = {'name': 'Alice', 'age': 30}
with open('example.json', 'w', encoding='utf-8') as my_file:
my_file.write(json.dumps(my_dict))
File content:
{"name": "Alice", "age": 30}
Solution 3: Write a Specific Dictionary Value
If you meant to write a specific string value from the dictionary:
my_dict = {'name': 'Alice', 'age': 30}
with open('example.txt', 'w', encoding='utf-8') as my_file:
my_file.write(my_dict['name']) # Write only the name
File content:
Alice
Handling TypeError: ... not tuple
Cause: Trying to write a tuple object directly to a file opened in text mode.
(Solutions are analogous to lists)
Solution 1: Join Tuple Elements into a String (str.join())
my_tuple = ('Alice', 'Bob', 'Carl')
with open('example.txt', 'w', encoding='utf-8') as my_file:
my_file.write(','.join(my_tuple)) # Join with commas
File content:
Alice,Bob,Carl
Ensure all tuple items are strings or convert them first.
Solution 2: Convert Tuple to String Representation (str())
my_tuple = ('Alice', 'Bob', 'Carl')
with open('example.txt', 'w', encoding='utf-8') as my_file:
my_file.write(str(my_tuple))
File content
('Alice', 'Bob', 'Carl')
Solution 3: Convert Tuple to JSON String (json.dumps())
import json
my_tuple = ('Alice', 'Bob', 'Carl')
with open('example.json', 'w', encoding='utf-8') as my_file:
my_file.write(json.dumps(my_tuple))
File content
["Alice", "Bob", "Carl"]
Handling TypeError: ... not None
Cause: Trying to write the None value to a file.
# Error Example:
# my_var = None
# with open('example.txt', 'w') as my_file:
# my_file.write(my_var) # ⛔️ TypeError
Identifying the Source of None
None values often arise from:
- Functions that don't explicitly
returna value. - Variables explicitly assigned
None. - Assigning the result of methods that modify in-place (like
list.sort(), which returnsNone).
Solution: Check for None Before Writing
Explicitly check if the variable is None and handle it, perhaps by writing an empty string or skipping the write:
my_str = None
with open('example.txt', 'w', encoding='utf-8') as my_file:
if my_str is not None:
my_file.write(my_str)
else:
my_file.write('') # Write an empty string instead
# Or simply `pass` to write nothing
Conclusion
The TypeError: write() argument must be str, not ... error is a direct consequence of trying to write non-string data to a file opened in text mode. The solution always involves converting the data to a string before calling write().
Choose the conversion method (str(), str.join(), json.dumps(), .decode()) that best suits the data type and your desired output format.
When dealing with bytes, ensure you open the file in the correct mode ('w' for text, 'wb' for binary).