TypeError: 'NoneType' object is not subscriptable

Quick answer

You used bracket indexing — x[0] or x["key"] — on a value that was None. None isn't a list, dict, or string, so it can't be subscripted. Find where the variable became None (a missing return, or a None-returning call) and fix it there, or guard the access.

The exact error string

Traceback (most recent call last):
  File "app.py", line 4, in <module>
    print(config["host"])
          ^^^^^^^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable

How to diagnose it in 30 seconds

The traceback line shows the subscript expression (config["host"]), so the thing before the brackets — config — is None. Don't patch the crash line. Ask: where did config get assigned, and what returned None there? That assignment is the bug.

Cause 1: function returned None

def load_config(path):
    if os.path.exists(path):
        return json.load(open(path))
    # ❌ no return on the else path -> None

config = load_config("missing.json")
print(config["host"])    # TypeError: 'NoneType' object is not subscriptable

# ✅ return a sensible default
def load_config(path):
    if os.path.exists(path):
        return json.load(open(path))
    return {}

Cause 2: assigning an in-place method's result

rows = [3, 1, 2]
rows = rows.sort()       # ❌ sort() returns None
first = rows[0]          # 'NoneType' object is not subscriptable

# ✅ sort in place, don't reassign
rows = [3, 1, 2]
rows.sort()
first = rows[0]

Cause 3: indexing a None from parsed JSON

import json
data = json.loads('{"user": null}')   # JSON null -> Python None
name = data["user"]["name"]            # ❌ data["user"] is None

# ✅ check the level, or default it
user = data.get("user") or {}
name = user.get("name")

Unsure which fields are null? Drop the payload into the JSON Formatter to see the structure before you index into it.

Cause 4: a query/lookup that found nothing

row = cursor.fetchone()   # no rows -> None
user_id = row[0]          # ❌ 'NoneType' object is not subscriptable

# ✅ guard for the empty result
row = cursor.fetchone()
if row is not None:
    user_id = row[0]

Common sources of the None

SourceReturns None whenSafe pattern
function with no returnsome/all pathsreturn a default ({}/[])
list.sort()/.append()always (in-place)don't reassign the result
JSON null fieldfield is null/absent(x or {})[...] / .get
cursor.fetchone()no matching rowif row is not None:
dict.get(k)key missingdict.get(k, {})

Debugging checklist

Frequently Asked Questions

What does 'NoneType object is not subscriptable' mean?

You used square-bracket indexing — x[0] or x['key'] — on a value that was None. Subscripting (the [ ] operator) is only defined for sequences and mappings like list, str, dict, and tuple; None supports none of that, so Python raises TypeError.

Why is the value None instead of a list or dict?

Usually a function returned None (a missing or conditional return), or a None-returning API was used as if it returned a collection — json.load on the wrong thing, a dict.get with no default, list.sort() assigned to a variable, or a DB query that found no row.

How do I fix 'NoneType is not subscriptable'?

Trace the variable back to its assignment and confirm it can't be None. Fix the real source (add a return, pass a default), or guard the access: if x is not None: x[0], or x = func() or [] to fall back to an empty collection.

Why does this happen with json.loads or a JSON field?

JSON null decodes to Python None, so data['user']['name'] throws if 'user' is null. Also, assigning the result of json.dump (which returns None) by mistake and then indexing it triggers this. Inspect the JSON structure and check each level for None before indexing.

Why did list.sort() or .append() cause this?

In-place methods return None. If you write data = data.sort() or rows = rows.append(r), data/rows become None, and the next data[0] raises "not subscriptable". Call the method without reassigning its result.

What's the difference between 'not subscriptable' and 'has no attribute'?

"not subscriptable" is bracket access on None (x[0], x['key']). "has no attribute" is dot access on None (x.attr, x.method()). Both mean the value is None; the operation differs. The fix is the same: eliminate or guard the None.

Inspect the JSON that produced the None

If the None came from a parsed payload, format it to see which fields are null or missing before you index into them.

Open JSON Formatter 'NoneType' has no attribute All Error References
About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.