TypeError: String Indices Must Be Integers in Python

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] or text[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.

References

Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Daniel
Daniel
4 years ago

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

Last edited 4 years ago by Pratik Kinage
Pratik Kinage
Admin
4 years ago
Reply to  Daniel

Check your data[‘main’]. It probably contains string.