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.
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.