TypeError
string indices
programming error
Python
debugging

Why am I seeing TypeError string indices must be integers?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

TypeError: string indices must be integers means you are using a string key (like ["name"]) to index into a value that is a str, not a dict. Python strings can only be indexed with integers (e.g., s[0], s[1:3]). The error almost always happens because a variable you expect to be a dictionary or a parsed JSON object is actually still a raw JSON string, or because you are iterating over a data structure and getting individual items where you expected nested objects.

The Most Common Cause: Unparsed JSON

python
1import json
2
3# This is a string, not a dictionary
4response = '{"name": "Alice", "age": 30}'
5
6# WRONG — response is a str, not a dict
7print(response["name"])
8# TypeError: string indices must be integers
9
10# FIX — parse the JSON string first
11data = json.loads(response)
12print(data["name"])  # Alice

This happens frequently with HTTP responses:

python
1import requests
2
3resp = requests.get("https://api.example.com/user/1")
4
5# WRONG — resp.text is a string
6print(resp.text["name"])  # TypeError
7
8# FIX — parse the response
9data = resp.json()  # or json.loads(resp.text)
10print(data["name"])  # Alice

Iterating Over a Dict Gets Keys, Not Items

python
1user = {"name": "Alice", "age": 30, "city": "NYC"}
2
3# WRONG — iterating over a dict yields keys (which are strings)
4for item in user:
5    print(item["name"])
6    # First iteration: item = "name" (a string)
7    # TypeError: string indices must be integers
8
9# FIX — iterate over items if you need key-value pairs
10for key, value in user.items():
11    print(f"{key}: {value}")
12
13# Or access the dict directly
14print(user["name"])

Iterating Over a List of Dicts

python
1users = [
2    {"name": "Alice", "age": 30},
3    {"name": "Bob", "age": 25},
4]
5
6# CORRECT — each item is a dict
7for user in users:
8    print(user["name"])  # Works
9
10# But if your data is a JSON string of a list:
11users_json = '[{"name": "Alice"}, {"name": "Bob"}]'
12
13# WRONG — iterating over a string gives characters
14for user in users_json:
15    print(user["name"])  # TypeError (user is a single character)
16
17# FIX — parse first
18import json
19for user in json.loads(users_json):
20    print(user["name"])  # Alice, Bob

Nested JSON Gotcha

python
1import json
2
3data = {
4    "user": '{"name": "Alice", "age": 30}'  # Value is a string, not a nested dict
5}
6
7# WRONG — data["user"] is a string
8print(data["user"]["name"])  # TypeError
9
10# FIX — parse the nested JSON string
11user = json.loads(data["user"])
12print(user["name"])  # Alice

Some APIs return nested JSON as an escaped string within the outer JSON. Always check the type before indexing.

Debugging Strategy

When you hit this error, the first step is to check what type your variable actually is:

python
1value = get_some_data()
2
3# Before indexing, verify the type
4print(type(value))   # <class 'str'> — this is your problem
5print(repr(value))   # Shows the actual content, including quotes
6
7# Then fix based on what you find
8if isinstance(value, str):
9    import json
10    value = json.loads(value)
11
12print(value["key"])  # Now works

String Indexing Review

Strings support only integer indices and slices:

python
1s = "hello"
2
3# Valid string operations
4print(s[0])      # 'h'
5print(s[-1])     # 'o'
6print(s[1:4])    # 'ell'
7print(s[::-1])   # 'olleh'
8
9# Invalid — these all raise TypeError
10# print(s["h"])
11# print(s[0.5])
12# print(s[None])

Common Scenarios That Trigger This Error

ScenarioWhat You HaveWhat You ExpectedFix
API response not parsedstrdictCall .json() or json.loads()
Iterating over dictKey strDict itemUse .items() or index the dict directly
Nested JSON stringstr field in dictNested dictjson.loads() the inner string
CSV fieldstr valuedictParse with csv.DictReader or split
YAML not parsedstrdictyaml.safe_load() the string

Common Pitfalls

  • Forgetting to parse API responses: requests.get().text is a string. Use .json() to get a dictionary. If the API returns non-JSON, check Content-Type headers.
  • Double-encoded JSON: Some APIs return JSON where string values contain escaped JSON. You need to call json.loads() twice — once for the outer string, once for the inner.
  • Iterating over a dict vs a list of dicts: for x in my_dict gives you keys (strings). for x in my_list_of_dicts gives you dicts. Check your data shape.
  • YAML or config files read as strings: open("config.yaml").read() gives you a string. Use yaml.safe_load(open("config.yaml")) to get a dictionary.
  • Pandas DataFrame confusion: df["column"] works on DataFrames, but if you accidentally have a string instead of a DataFrame, you get this error. Verify with type(df).

Summary

  • This error means you are indexing a string with a non-integer key like ["name"]
  • The most common cause is treating an unparsed JSON string as a dictionary
  • Fix by parsing the string first: json.loads(string) or response.json()
  • Always check type(variable) and repr(variable) when debugging
  • When iterating over a dict, you get keys (strings), not values — use .items() for key-value pairs
  • Use isinstance(value, str) to guard against type confusion before indexing

Course illustration
Course illustration

All Rights Reserved.