DEV Community

Nico Reyes
Nico Reyes

Posted on

Python threw 'TypeError'. Took 4 hours to realize what it actually meant.

Python threw 'TypeError'. Took 4 hours to realize what it actually meant.

Python exceptions look helpful until they lie to you.

Had a function that took two arguments. Called it with a dict and a list. Python said TypeError, expected something else. Simple enough, right?

Except it wasn't.

The setup

I'm building this small script to merge two data sources. One gives me a dict of user IDs to emails. The other gives me a list of tuples with (user_id, signup_date). I need to combine them into one clean structure.

def merge_users(user_data, signup_list):
    result = {}
    for user_id, email in user_data.items():
        result[user_id] = {
            'email': email,
            'signup_date': None
        }

    for user_id, date in signup_list:
        if user_id in result:
            result[user_id]['signup_date'] = date

    return result
Enter fullscreen mode Exit fullscreen mode

Classic stuff. Straightforward.

Then I call it:

user_emails = {'u1': 'alice@example.com', 'u2': 'bob@example.com'}
signups = [('u1', '2026-01-15'), ('u2', '2026-02-20')]

merged = merge_users(user_emails, signups)
Enter fullscreen mode Exit fullscreen mode

TypeError. Something about unhashable type 'list'.

What I tried

First thought: I probably passed something wrong. Checked my call. User_data is a dict, signup_list is a list of tuples. Should work.

Maybe the dict has nested lists as keys? Double-checked. Nope, just normal string keys.

Maybe Python version issue? I was on 3.11, tried 3.12. Same error.

Spent an hour looking at the function. Then I decided to simplify. Strip out everything except the essentials. Make it as barebones as possible.

Still failing.

That's when it hit me. The error wasn't coming from my function. It was coming from somewhere else in the call stack.
Turns out the actual call was wrapped in some validation helper I forgot I had. It was doing something like data.get('users', {}).items() but data was sometimes returning a list instead of a dict because of some legacy field naming.

Python's error message pointed at my merge function because that's where the exception propagated. But the actual problem was three stack frames earlier.

The fix

# Before (broken)
data = some_api_call()
users = data.get('users', {})
merged = merge_users(users, signups)

# After (working)
data = some_api_call()
users = data.get('users') or {}
# Also handle the case where users might be a list
if isinstance(users, list):
    users = {u['id']: u['email'] for u in users}
merged = merge_users(users, signups)
Enter fullscreen mode Exit fullscreen mode

Finding that took forever because I trusted the error message too much. Still annoyed about it tbh.

Top comments (0)