“Subscriptable” means “you can index it with brackets” — like data[0] or record["name"]. This error says the thing you indexed is None: Python’s nothing-here value. The bug is never at the indexing line itself; it’s earlier, where the value that was supposed to hold your data quietly became None instead.
print(type(data), data) for the indexed value — or read the traceback: the last line names the exact expression.list.sort(), list.append(), list.reverse() and friends change the list and return None. data = data.sort() throws the sorted data away and keeps the None. Call the method on its own line instead.re.search() returns None when there’s no match; dict.get() returns None for a missing key; input helpers and database lookups do the same. Guard before indexing: if match: ... match.group(1).return, the caller gets None — and the error shows up later, somewhere else entirely.response.json().get("results") is None when the key is absent or the request failed — print the raw response once before parsing it.The general habit that prevents this error: the moment a value crosses a boundary (a function return, an API response, a file read), check for None there — not ten lines later where it explodes. Python even gives you the pattern: `value = maybe() or default` when a sensible default exists.
What does “subscriptable” mean? Capable of being subscripted — accessed with square brackets, like list[0] or dict["key"]. Strings, lists, tuples and dicts are subscriptable; None is not, and neither are numbers.
Why is the error line not where the bug is? None travels. It’s created at the place that failed to produce a value, then stored, passed and returned until something tries to use it — and that use is where Python finally complains.