TypeError: string indices must be integers means Python is treating a value as a string, but your code is indexing it as if it were a dictionary, list of dictionaries, or another keyed object. Strings are sequences of characters. They accept integer positions and slices, not string keys.
The fix is to check what type the variable really has at the failing line. If it is a string, use an integer index such as text[0] or parse the string into the data structure you expected. If it is supposed to be a dictionary, make sure your code is working with the dictionary object, not a JSON string or a dictionary key.
Why the Error Happens
The simplest way to reproduce the error is to use a string key on a string value. Python cannot look up a character by the key "p"; it can only look up characters by numeric positions.
message = "python"
print(message["p"])
The variable message is a string. To read from a string, use an integer index or a slice. Index 0 means the first character, index 1 means the second character, and so on. When the traceback says not 'str' at the end, it is giving the same clue: your index value is a string, but Python expected an integer position.
Use Integer Indexes and Slices for Strings
Use this form when your value really is text and you want characters from it. A slice can return more than one character while still using integer boundaries.
message = "python"
print(message[0])
print(message[1:4])
This prints the first character and then a substring. If you are validating user input, PythonPool’s guide to checking whether a string is an integer may also be useful. Keep string indexing for character work; do not use it as a substitute for parsing structured data.
Parse JSON Before Using Dictionary Keys
A very common cause is API or file data that looks like a dictionary but is still a JSON string. String data must be parsed before you can access keys such as "user" or "score".
payload = '{"user": "Ada", "score": 91}'
print(payload["user"])
The code above fails because payload is text. Parse it with json.loads() first, then access dictionary keys.
import json
payload = '{"user": "Ada", "score": 91}'
data = json.loads(payload)
print(data["user"])
print(data["score"])
This works because data is now a dictionary. The string key belongs on the dictionary, not on the raw JSON string. This pattern appears often after reading from files, receiving HTTP responses, or loading values from environment variables.
Watch Dictionary Loops
Another common bug appears when looping over a dictionary. Iterating over a dictionary directly gives you its keys. Those keys are often strings, so indexing the key as if it were a nested dictionary produces this TypeError.
person = {"name": "Ada", "language": "Python"}
for key in person:
print(key["name"])
Here key is first "name" and then "language". Each key is a string, not a dictionary. Use .items() when you need both keys and values.
person = {"name": "Ada", "language": "Python"}
for key, value in person.items():
print(key, value)
If your data is a list of dictionaries, loop through the list and then index each dictionary: user["name"]. PythonPool’s guides to iterating through lists and finding strings in lists cover the related list patterns.
How to Debug the Failing Line
At the line that raises the error, print or inspect the variable before indexing it. If type(value) is str, use integer indexes, parse it, or follow the code path backward to find where the wrong type was assigned. If the value should be a dictionary, confirm that the parser ran successfully and that the variable was not overwritten later.
Do not patch this error by blindly changing the index to 0. That may hide the crash while returning the wrong character from a string. The correct fix should match the data model: character access for strings, key lookup for dictionaries, and row-by-row access for lists of dictionaries.
This error is different from trying to subscript a number. If your traceback says an integer is not subscriptable, see PythonPool’s TypeError: int object is not subscriptable guide. If the traceback is related to NumPy scalar conversion, the only size-1 arrays can be converted to Python scalars guide covers that separate issue.
Checklist
- Use
text[0]ortext[start:end]for strings. - Use
json.loads()before accessing keys from JSON text. - Use
dict.items()when looping through dictionary keys and values. - Check
type(value)at the failing line if the data shape is unclear.
Hi,
Thanks for the article, very informative. However you didn’t show how you’d solve this issue for the JSON example.
How would you get “26.96” from
for i in data['main']:print(i['temp'])
without running into this error? I’m testing it on VS Code and while the first ‘for’ works because it’s an array, the 2nd one throws the error.
Thanks in advance,
Daniel
Check your data[‘main’]. It probably contains string.