Home › Python

TypeError: string indices must be integers — how to fix

Traceback (most recent call last):
  File "app.py", line 5, in <module>
    print(user["name"])
TypeError: string indices must be integers, not 'str'

Quick fix: Check type(x) — it is a str, not a dict. Parse JSON first with data = json.loads(text) (or response.json()), and iterate dicts with for k, v in d.items() instead of for item in d.

What it means

Strings can only be indexed by integers (s[0]) or slices (s[1:4]). When you write x["name"] and x turns out to be a str, Python raises this error. Python 3.11+ phrases it as string indices must be integers, not 'str'.

The fix is almost never in the line that fails — it's in wherever x became a string. Print it first:

print(type(user), repr(user)[:200])

Cause 1: JSON that was never parsed

import requests
r = requests.get("https://api.example.com/user/1")
user = r.text              # a str!
print(user["name"])        # TypeError

Fix: decode the JSON into Python objects.

user = r.json()            # dict
# or, for text from a file / message queue:
import json
user = json.loads(text)
# from a file:
with open("user.json") as f:
    user = json.load(f)

A related trap is double-encoded JSON: json.loads() returns a str again because the payload was serialized twice ("{\"name\": \"a\"}"). Calling json.loads() a second time works, but fixing the producer (don't json.dumps something that's already a JSON string) is better.

Cause 2: iterating over a dict gives keys, not values

users = {"alice": {"age": 30}, "bob": {"age": 25}}
for u in users:
    print(u["age"])        # u is "alice" — a str

Fix:

for name, info in users.items():
    print(name, info["age"])

Cause 3: iterating over a dict when you expected a list

APIs often return {"results": [...]}. Looping over the top-level object yields its keys:

data = r.json()
for item in data:          # item == "results"
    print(item["id"])

Fix: loop over the list inside it.

for item in data["results"]:
    print(item["id"])

Cause 4: a slice written with commas or a float index

s = "hello"
s[1, 3]      # TypeError: string indices must be integers (tuple)
s[len(s)/2]  # float index -> "string indices must be integers"

Fix:

s[1:3]
s[len(s) // 2]   # integer division

Cause 5: a CSV/form value that is a string

csv.reader rows, input(), sys.argv and request.form values are all strings. If you index into them with a key, you get this error. Use csv.DictReader if you want rows keyed by column name:

import csv
with open("users.csv", newline="") as f:
    for row in csv.DictReader(f):
        print(row["name"])

Quick checklist

Last updated 2026-11-03.