Int Object Is Not Subscriptable | Fix Indexing Errors

The int object is not subscriptable error means you indexed a number like a list; fix it by indexing the real container or keeping the value as a container.

You’ll see this error when Python reads square brackets right after an integer and stops the program. It’s not being picky. It’s saving you from code that “runs” while doing the wrong thing.

If you’ve ever thought, “This variable was a list a second ago,” you’re already close to the fix. Most cases come down to one issue: a value that changed shape without you noticing.

What “Not Subscriptable” Means In Plain Python

In Python, brackets are for pulling an item out of a container. Lists, tuples, strings, dictionaries, and many library objects can be accessed with []. An int can’t, since it’s a single number, not a collection.

That’s why code such as 42[0] explodes. Python can’t interpret “index zero of forty-two,” so it throws TypeError: 'int' object is not subscriptable and points at the brackets.

Quick check: Look one token to the left of the [. Ask yourself what that thing is right now, not what you meant it to be.

How To Confirm The Type Fast

Before you change code, confirm the type at the crash line. A name that held a list earlier can hold a number later, especially after a refactor.

  • Print The Type — Add print(type(x), x) on the line before the crash, run once, then remove it.
  • Step Through Once — Use a debugger breakpoint right above the failing line and watch the variable update.
  • Search For Overwrites — Use your editor search for x = and scan where the value changes.

Int Object Is Not Subscriptable In Python When Data Shapes Drift

The most common cause is “shape drift.” You expect a container, yet you’re holding a single number by the time you index it. This shows up in loops, parsing, and code that started small and grew.

It can feel confusing because the variable name still sounds like a container. Your brain reads values[0] and assumes “values is a list.” Python reads it and sees “values is an int.”

Common Triggers You Can Spot Right Away

Trigger What It Looks Like Fix Direction
Indexing A Number n[0] Index the real container or keep n as a container
Wrong Unpack a, b = item then a[0] Confirm item is a sequence and name parts clearly
Return Type Surprise row = func() then row[1] Align caller code with what the function returns
Name Shadowing list = 3 then list[0] Rename variables that collide with built-ins or earlier containers
Math Then Brackets (x + y)[0] Index before math, or store the container first

Once you know which bucket you’re in, the fix is usually small. The key is changing the source of the wrong shape, not just patching the crash line.

Fix Patterns That Solve The Error Cleanly

When you see brackets after a variable, there are only a few valid intentions. You either meant to index a list or tuple, grab a dict value by key, slice a string, or select from an array-like object.

Pick your intention, then make the data match it. Guessing often “fixes” the error while breaking the result.

Pattern 1: You Meant To Index A List, Yet You Stored One Number

This happens when you reduce a list to a single value and keep using the old name out of habit.

# You start with a list
scores = [10, 20, 30]

# Later you overwrite the same name with one number
scores = scores[0]

# Then you try to index it again
print(scores[0])  # TypeError
  • Keep Names Honest — Use scores for the list and score for one number.
  • Index Before Reducing — If you only need one element, pull it out once, then use it as a number.
  • Fix The Overwrite — If a helper should return a list, keep it returning a list and adjust the helper, not every caller.

Pattern 2: You Meant A Dict Key, Yet You’re Holding The Id

Another common slip is mixing “the object” with “a field from the object.” You might expect user["id"], then later store only the id back into user.

Deeper fix: Keep the dict and the id as separate variables. That one choice removes a lot of confusion in larger files.

  • Use Clear Pair Namesuser for the dict, user_id for the integer.
  • Validate At Boundaries — If a function expects a dict, check it early and fail with a readable message.
  • Parse Once — Convert raw input into a dict structure in one place, then pass that structure around.

Pattern 3: You Thought A Function Returned A Sequence

Many functions return a single count, boolean, or id. If you treat that return as a list, you’ll index an int and hit the error.

# This returns an int
count = len(items)

# Treating it like a list triggers the crash
print(count[0])
  • Check The Return — Read the function docstring or the implementation and confirm the return type.
  • Split “One” And “Many” Helpers — Use separate functions for one item versus a list of items.
  • Add Type Hints — A hint like def count_items(...) -> int lets many editors warn you before runtime.

Debug Walkthroughs In The Usual Trouble Spots

Context is what makes the fix stick. These are the spots where int object is not subscriptable shows up most often, even for experienced Python devs.

Loops Where A Variable Changes Meaning

A loop variable is usually one element. If you later treat it as the whole list, you’ll end up indexing a scalar.

nums = [5, 6, 7]

for num in nums:
    # num is an int on every iteration
    print(num[0])  # TypeError
  • Index The Container — Use nums[0] outside the loop when you want the first element.
  • Keep One Level Per Block — A block handling one element should not switch to list-level indexing.
  • Log One Iteration — Print type and value once to confirm your mental model, then delete the print.

CSV And JSON Parsing That Collapses A Row Early

Parsing code often pulls one column too soon. Later code still assumes it has the full row.

  • Store The Full Row First — Keep row as a list or dict, then store age = row[2] in a new name.
  • Guard Missing Fields — Check length or key presence before indexing so bad input fails cleanly.
  • Convert Types Once — Convert string digits to ints in one section, then keep them as ints.

Pandas And Numpy Cases Where You End Up With A Scalar

In data code, you can select a single cell and end up with a scalar. Scalars don’t behave like arrays, so bracket indexing may break once you’ve reduced the shape.

  • Inspect Selection Results — Print the type right after selection to see if you got a Series, array, or scalar.
  • Choose One Access Style — Stick with .loc or .iloc and be clear when you want a slice versus one cell.
  • Delay Scalar Conversion — Keep array-like objects until the final step if later code expects indexing.

Prevention Habits That Stop Repeat Errors

Fixing the crash line is step one. Preventing the next one is about habits that keep your data shapes clear even when the file changes.

Naming That Makes Wrong Indexing Feel Wrong

Names are your early warning system. If a variable called scores turns into a single number, that mismatch should look strange right away.

  • Use Plurals For Containersusers, items, scores for lists, tuples, dicts, and arrays.
  • Use Singular For One Valueuser, item, score for one element or one scalar.
  • Avoid Built-In Names — Don’t name variables list, dict, int, or sum.

Type Hints And Editor Checks That Catch It Early

Static checks can catch “indexing an int” before you run the program. That’s especially handy when the failing path only happens with certain inputs.

  • Hint Return Types First — Start with function returns, then add hints to main data structures.
  • Turn On Warnings — Let your editor flag suspicious subscripts once it knows types.
  • Add Small Assertions — A simple assert isinstance(rows, list) can act as a tripwire in scripts.

Guard Rails For Inputs That Flip Types

User input is where types often flip. A CLI argument starts as text, then becomes a number. If you store that number back into a name that used to hold a list, you set up a later crash.

  • Parse Into New Names — Keep raw_value and parsed_value separate.
  • Check Range Before Indexing — Validate indexes and lengths before you pull items out of a container.
  • Raise Clear Errors — Say what type you got and what you expected, so the next person fixes it fast.

Int Object Is Not Subscriptable Quick Checklist

When you just want the fix and you’re staring at a traceback, this checklist keeps you focused on the right step each time.

  1. Find The Brackets — Go to the traceback line and locate the exact [ that triggered the crash.
  2. Point At The Left Side — Identify the value right before the bracket and name it.
  3. Confirm The Type — Print type(x) or inspect it in your debugger at that line.
  4. Pick The Intended Shape — Decide “number” or “container,” then change the code to match.
  5. Fix The Source — Find where the value became an int and adjust that spot, not just the crash line.
  6. Lock The Fix In — Rename, add a type hint, or add a small assertion to prevent repeats.

If you still see int object is not subscriptable after one fix, search for a second overwrite of the same variable name on another branch. That’s a classic “it worked once” trap.

Once you treat names and shapes as part of your code’s story, this error stops feeling random. It becomes a clear signal that your data changed without your code changing with it.