Skip to content

How to Resolve "TypeError: can only concatenate str (not 'NoneType') to str" in Python

How to fix the Python TypeError when concatenating strings with None values, including solutions like f-strings, None checks, and source fixes.

String concatenation is one of the most basic operations in Python, but it can trip you up when one of the values you're trying to join turns out to be None instead of a string. The error TypeError: can only concatenate str (not 'NoneType') to str is Python's way of telling you that you're trying to glue a string together with something that isn't a string. In this guide, we'll explore why this happens, look at the most common scenarios that cause it, and walk through multiple ways to fix it.

Understanding the Error

In Python, the + operator can concatenate two strings together, but both operands must be strings. If either side is None (which has the type NoneType), Python doesn't know how to combine them and raises a TypeError.

❌ Example that triggers the error:

name = "Alice"
greeting = "Hello, " + name + "!"
title = None

message = greeting + title
print(message)

Output:

TypeError: can only concatenate str (not 'NoneType') to str

Python is explicit here: it tells you it expected a str but received a NoneType. The fix always involves ensuring the value is a string before concatenation.

Common Causes

Before jumping to solutions, it's important to understand where None values typically come from so you can prevent the error at its source.

1. Functions That Don't Return a Value

Any Python function that doesn't explicitly return something returns None by default:

def get_username(user_id):
    if user_id == 1:
        return "Alice"

username = get_username(2)
print("Welcome, " + username)  # TypeError!

2. Dictionary Lookups with .get()

The dict.get() method returns None when the key doesn't exist (unless you specify a default):

config = {"host": "localhost"}
port = config.get("port")  # Returns None: key doesn't exist

connection_string = "Connecting to " + config.get("host") + ":" + port  # TypeError!

3. Variables Assigned Conditionally

Variables that are only assigned under certain conditions may remain None:

title = None

if some_condition:
    title = "Manager"

message = "Title: " + title  # TypeError if some_condition was False

4. External Data Sources

Data from APIs, databases, CSV files, or user input can contain None or null values unexpectedly.

How to Fix It

Solution 1: Check for None Before Concatenating

The most explicit approach is to check whether the value is None and handle it accordingly:

title = None

if title is not None:
    message = "Title: " + title
else:
    message = "Title: Not Provided"

print(message)

Output:

Title: Not Provided

This approach makes your intent clear and is easy to read.

Solution 2: Use the or Operator to Provide a Default

The or operator returns the first truthy value, which makes it a concise way to replace None (or any falsy value) with a default string:

title = None

message = "Title: " + (title or "Unknown")
print(message)

Output:

Title: Unknown

F-strings (Python 3.6+) automatically convert values to their string representation, so None becomes the string "None" instead of raising an error:

title = None

message = f"Title: {title}"
print(message)

Output:

Title: None

To display a custom fallback instead of the word "None", combine f-strings with a ternary expression:

title = None

message = f"Title: {title if title is not None else 'Not Provided'}"
print(message)

Output:

Title: Not Provided

Solution 4: Use str.format()

The format() method behaves similarly to f-strings and handles None without raising an error:

title = None

message = "Title: {}".format(title if title is not None else "Not Provided")
print(message)

Output:

Title: Not Provided

Solution 5: Convert to String with str()

If you simply want None to appear as text (or want a universal conversion), wrap the variable in str():

title = None

message = "Title: " + str(title)
print(message)

Output:

Title: None

Solution 6: Fix the Source of None

Often the best fix is to prevent None from appearing in the first place. If a function can return None, update it to always return a string:

❌ Wrong: Function implicitly returns None:

def get_username(user_id):
    if user_id == 1:
        return "Alice"

✅ Correct: Function always returns a string:

def get_username(user_id):
    if user_id == 1:
        return "Alice"
    return "Guest"  # Explicit default return value

For dictionary lookups, always provide a default with .get():

config = {"host": "localhost"}

port = config.get("port", "5432")

connection_string = f"Connecting to {config.get('host')}:{port}"
print(connection_string)

Output:

Connecting to localhost:5432

Practical Example: Building a User Profile String

Here's a real-world scenario that combines multiple techniques:

def build_profile_summary(user):
    """Build a profile summary string, handling missing fields gracefully."""
    name = user.get("name") or "Anonymous"
    email = user.get("email") or "No email provided"
    bio = user.get("bio")

    summary = f"Name: {name}\n"
    summary += f"Email: {email}\n"
    summary += f"Bio: {bio if bio is not None else 'This user has not added a bio.'}"

    return summary


user1 = {"name": "Alice", "email": "alice@example.com", "bio": "Python developer"}
print(build_profile_summary(user1))

print()

user2 = {"name": None, "email": None}
print(build_profile_summary(user2))

Output:

Name: Alice
Email: alice@example.com
Bio: Python developer

Name: Anonymous
Email: No email provided
Bio: This user has not added a bio.

Solutions at a Glance

Approach Example Best For
Check for None if x is not None: ... Explicit control flow
or operator x or "default" Quick one-liner defaults
f-strings with ternary f"{x if x is not None else 'default'}" Clean, readable formatting
str() conversion str(x) Debugging / quick fixes
Fix the source Return a default from functions Preventing the problem entirely
.get() with default dict.get(key, "default") Dictionary lookups

Conclusion

The TypeError: can only concatenate str (not 'NoneType') to str error occurs whenever you try to use the + operator to join a string with a None value.

The best approach depends on your situation: use f-strings with a ternary expression for clean inline formatting, the or operator for quick defaults, or an explicit None check when you need more control.

However, the most robust fix is often to prevent None from reaching the concatenation in the first place, i.e. by ensuring your functions always return strings and your dictionary lookups include default values.

Navigation