← Debugging Guides

阅读中文版本

Python TypeError: 'NoneType' Object Is Not Subscriptable

Fix TypeError 'NoneType' object is not subscriptable by tracing the function that returned None and guarding before indexing.

beginnerdebuggingpythontypeerrornull

Symptoms

  • TypeError: 'NoneType' object is not subscriptable at data[0]
  • The failing line worked with some inputs but not others
  • A helper used to return a value but now returns None

Possible causes

  • A function falls through without an explicit return, yielding None
  • A dict.get(key) without a default returns None for a missing key
  • An API call failed and its error path returned None instead of raising

Diagnosis steps

Find who produced the None

python -X dev -c "import traceback; print(traceback.format_exc())"

Interpretation

The traceback frames above the failing subscript point to the call that returned None.

Probe the value at the call site

print(repr(data), type(data))

Interpretation

Confirming the value is None and which function produced it fixes the guesswork.

Root cause

Subscripting calls __getitem__, which None does not implement. The real defect is upstream: a function or lookup returned None, often by falling through without a return or by using get() without a default.

Fix

Return an explicit value from every code path, use data.get(key, default) with a real default, and validate or raise a meaningful error before indexing.

Risk note

Silently substituting an empty container for None hides bugs; prefer failing fast at the boundary.

Verify the fix

Rerun with the previously failing input and confirm no TypeError. Add a test asserting the helper returns a container for the missing-key case.

Symptoms

This guide profiles the failure behind “Python TypeError: ‘NoneType’ Object Is Not Subscriptable”. It walks through the observable symptoms, a reproducible diagnosis path, the underlying root cause, the concrete fix, and how to verify the change and prevent a regression.

Observed symptoms include:

  • TypeError: ‘NoneType’ object is not subscriptable at data[0]
  • The failing line worked with some inputs but not others
  • A helper used to return a value but now returns None

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Find who produced the None

python -X dev -c "import traceback; print(traceback.format_exc())"

The traceback frames above the failing subscript point to the call that returned None.

Step 2: Probe the value at the call site

print(repr(data), type(data))

Confirming the value is None and which function produced it fixes the guesswork.

Likely contributors, in order of frequency:

  • A function falls through without an explicit return, yielding None
  • A dict.get(key) without a default returns None for a missing key
  • An API call failed and its error path returned None instead of raising

Root Cause

Subscripting calls getitem, which None does not implement. The real defect is upstream: a function or lookup returned None, often by falling through without a return or by using get() without a default.

The Fix

Return an explicit value from every code path, use data.get(key, default) with a real default, and validate or raise a meaningful error before indexing.

Watch out: Silently substituting an empty container for None hides bugs; prefer failing fast at the boundary.

def load_config(raw):          # ❌ falls through -> None
    if raw:
        return raw

cfg = load_config('')          # None
# print(cfg['db'])            # TypeError: 'NoneType' object is not subscriptable

# ✅ explicit fallback
cfg = load_config('') or {}
print(cfg.get('db', 'sqlite:///app.db'))

Verify and Prevent

Rerun with the previously failing input and confirm no TypeError. Add a test asserting the helper returns a container for the missing-key case.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.