PIE / KID / 01
Python and AI for kids
Turtle drawings, games, first blocks.
Open the syllabusUnited States · Grade 3 to college · Python errors
An IndentationError is one of the first Python errors a new programmer meets, and its message rarely says what to change. This page reads each message the way Python means it, shows how Python actually counts the spaces at the start of a line, and gives a routine that fixes the error in any editor a US school uses, from IDLE and VS Code to a notebook in the browser. Every error message below comes from the Python documentation or from our own run of Python 3.13.6, and each one is labelled.
Live teaching since 2020 · 10,000+ students · Python from Grade 3 upward
In short
A Python IndentationError means the spaces at the start of a line do not fit the block structure Python expects: a block after a colon is missing, a line is indented for no reason, or a line steps back to a level that never existed. TabError, its subclass, means tabs and spaces were mixed. Re-indent the block with 4 spaces per level. Modern Age Coders teaches Python live to students from Grade 3 up, in a batch or one to one.
Learn Python with a teacher
Each course starts with the structure of a program, so indentation errors become rare rather than mysterious.

PIE / 01
Grades 3 to 8. Turtle art, games, and blocks of code a child can see.
Open the syllabus →
PIE / 02
Ages 13 to 18. From the first loop to full projects.
Open the syllabus →
PIE / 03
Ages 18 and up. Zero to advanced, live.
Open the syllabus →The messages
Python reports every indentation problem as an IndentationError or its stricter cousin, TabError. The Python documentation describes IndentationError as the "Base class for syntax errors related to incorrect indentation" and notes that it is a subclass of SyntaxError, which is why the program stops before a single line runs.
| Message | What Python found | The usual fix |
|---|---|---|
| expected an indented block after 'for' statement on line 2 | A line ending in a colon (for, if, while, def, class, else) with no indented line under it | Indent the body 4 spaces, or write pass if the body is not ready |
| unexpected indent | A line pushed right when nothing above it opened a block | Move the line back to the level of the line above |
| unindent does not match any outer indentation level | A line stepped back to a column no earlier line used | Line it up exactly with the block it belongs to |
| inconsistent use of tabs and spaces in indentation | Tabs and spaces mixed so that the meaning depends on tab width (this one is a TabError) | Convert the whole file to spaces |
| expected an indented block after function definition on line 1 | A def with only a comment, or nothing, underneath | Add the body, or pass as a placeholder |
Python reports the line where it noticed the problem, not the line you need to edit. For "expected an indented block", the line printed is the first line that should have been indented, and the line named at the end of the message is the one with the colon. Read both.
When the block is empty and the file ends, our run pointed at a comment line: a line that holds only a comment is ignored by Python (the documentation says such a line "is ignored"), so a comment can never be the body of a loop or a function.
Python 3.10 added the extra context. Its release notes show the message as "IndentationError: expected an indented block after 'if' statement in line 2", with the word "in".
Our run of Python 3.13.6 printed "on line 2" instead. If your school laptop runs an older Python, the message may be shorter, but the meaning and the fix are the same.
Sources, read 17 October 2026: Built-in Exceptions, What is new in Python 3.10, and our own runs of Python 3.13.6 on Windows 11 (file paths shortened to the file name). We are not connected with the Python Software Foundation.
Broken, then fixed
A student counts quiz answers, presses Run, and gets an error before anything prints. The loop line ends in a colon, which promises a block, and the next line breaks the promise.
# quiz_score.py (broken on purpose, ours) score = 0 for answer in ["a", "b", "c"]: score = score + 1 print(score) # Our run, Python 3.13.6: # File "quiz_score.py", line 3 # score = score + 1 # ^^^^^ # IndentationError: expected an indented block # after 'for' statement on line 2
The caret sits under the first word of line 3, the line that should have moved right. The end of the message names line 2, the line that opened the block.
# quiz_score.py (fixed, ours)
score = 0
for answer in ["a", "b", "c"]:
score = score + 1 # 4 spaces: inside the loop
print(score) # back at 0: after the loop
# Our run prints: 3The print line stays at the left margin on purpose: it runs once, after the loop. Indent it too and the program prints 1, 2 and 3 on separate lines, a logic change rather than an error.
The Python tutorial puts it plainly: "indentation is Python’s way of grouping statements." In many languages braces mark a block and spacing is only style. In Python, moving a line four spaces changes which block it belongs to.
That is why the fixed program above and a version with print indented are both valid Python but do different things. The error only appears when the spacing makes no sense at all.
Find the line that ends in a colon just above the error. Every line that should run as part of that loop, if or function must start further right than the colon line, and all of them by the same amount.
The tutorial states the same rule: "each line within a basic block must be indented by the same amount." Three spaces on one line and four on the next is enough to stop the program.
How Python counts
The Python language reference describes the exact rule, and once a student sees it, "unindent does not match any outer indentation level" stops being mysterious. Python keeps a stack of indentation levels, starting with a single zero, and compares each new line against the top of it.
# grade.py (broken on purpose, ours)
def grade(points):
if points >= 90:
return "A"
return "B" # 6 spaces: matches no level
# Our run, Python 3.13.6:
# File "grade.py", line 4
# return "B"
# ^
# IndentationError: unindent does not match
# any outer indentation levelLine 4 starts at column 6. Python has only seen levels 0, 4 and 8, so it cannot tell which block the return belongs to.
| Line | Leading spaces | Stack before the line | What Python does |
|---|---|---|---|
| 1 def grade(points): | 0 | [0] | Equal to the top: nothing happens |
| 2 if points >= 90: | 4 | [0] | Larger: push 4, one INDENT |
| 3 return "A" | 8 | [0, 4] | Larger: push 8, one INDENT |
| 4 return "B" | 6 | [0, 4, 8] | Smaller, but 6 is not on the stack: IndentationError |
The reference says that when a line is indented less than the one before, its level "must be one of the numbers occurring on the stack". Python pops levels until it reaches that number, producing one DEDENT for each.
Moving line 4 to 4 spaces makes it a DEDENT back to the if level, which means "otherwise, return B". Our run of the fixed file prints A B for grade(95) and grade(70).
Tabs are worth a variable number of spaces: the reference says each tab is replaced by one to eight spaces so that the column becomes a multiple of eight. A tab at the start of a line counts as 8; four spaces and then a tab also count as 8.
Two lines can therefore look identical on screen and mean different things. Python refuses to guess: if the meaning depends "on the worth of a tab in spaces", it raises TabError.
The fix routine
This is the routine our teachers walk students through, in this order. It works in IDLE, VS Code, PyCharm and browser notebooks, because it relies on Python's rules rather than any one editor.
# Unfinished function: Python needs a statement
def greet():
pass # placeholder until you write the body
print("hi")
# Our run prints: hi
# Without the pass line, Python 3.13.6 says:
# IndentationError: expected an indented block
# after function definition on line 1The Python tutorial describes pass as a statement that "does nothing" and can be used "when a statement is required syntactically but the program requires no action."
We ran python -m tabnanny on two of our broken files. It printed e4.py 3 followed by the line that began with a tab, and e7.py 4 followed by the line that used 8 spaces under tab-indented lines. That is the file, the line number and the exact line, which is all a student needs.
The Python documentation describes tabnanny as a tool for the "Detection of ambiguous indentation", intended for the time being to be called as a script.
Do not press space until the error goes away. The error may vanish while the logic breaks, for example when a line that should run once ends up inside a loop.
Do not paste a whole file into an AI chatbot and accept whatever comes back. We ask students to explain each block out loud first, because putting a block into words makes a misplaced line easier to spot.
Practice set
Our own practice set, written for this page and run on Python 3.13.6. Cover the right-hand column, decide what Python will say, then compare. It is practice for the idea, not anybody's homework.
| # | The program, line by line | What Python said |
|---|---|---|
| 1 | for i in range(3): / print(i) at the left margin | expected an indented block after 'for' statement on line 1 |
| 2 | total = 0 / then total = total + 5 with one leading space | unexpected indent |
| 3 | if True: / 4 spaces print("yes") / 2 spaces print("done") | unindent does not match any outer indentation level |
| 4 | while False: / 4 spaces # nothing yet | expected an indented block after 'while' statement on line 1 |
| 5 | def hello(): / 4 spaces then a one-line docstring | No error: a docstring is a statement, so the body is not empty |
| 6 | class Pet: / a blank line / print("ok") | expected an indented block after class definition on line 1 |
| 7 | if name == "Ava": / 4 spaces print("Hi Ava") / else: / print("Who are you?") at the margin | expected an indented block after 'else' statement on line 4 |
The body holds only a comment, and Python ignores comment-only lines, so the loop has no body at all. Replace the comment with pass, or keep the comment and add pass under it.
A string on its own line is a real statement, so a function whose body is only a docstring is valid. Many students expect an error here; seeing why there is none teaches what a block really needs.
else opens its own block, so it needs its own indented line. It is easy to fix the if half and forget that the else half follows exactly the same rule.
In your editor
US students write Python in whatever their class uses: IDLE on a school laptop, VS Code at home, a notebook in Google Colab, or a browser editor the teacher assigned. The rules are Python's, but each setting has its own usual cause.
| Where you write Python | The usual cause | What to check |
|---|---|---|
| Code copied from a web page or a PDF | Non-standard spaces, or tabs mixed with spaces | Delete the indentation and retype it with the Tab key in an editor set to spaces |
| A notebook cell (Colab or Jupyter) | A cell pasted half from one source, half from another | Re-indent the whole cell, then run that one cell |
| The interactive prompt (the >>> shell) | A compound statement not finished with a blank line | The tutorial says a compound statement typed interactively "must be followed by a blank line" |
| Two editors on one file | One saves tabs, the other saves spaces | Run python -m tabnanny, then convert the file to spaces |
| A long expression across lines | Worry that continuation lines need block indentation | Lines inside brackets may be indented freely; the reference says their indentation "is not important" |
The tutorial notes that "all decent text editors have an auto-indent facility." Let the editor indent after a colon, and use its option to show whitespace, so a tab and four spaces stop looking the same.
Many editors can convert a file's indentation to spaces in one command. Do that once per file and TabError disappears for good.
A student moving from block coding in elementary school to typed Python in middle or high school loses the visual nesting that blocks gave them. Indentation is that same nesting, written with spaces.
Students who go on to Java, the language of our AP Computer Science A course, keep the same habit: Java marks blocks with braces, but well-indented Java is far easier to read and debug.
Rules quoted from the Python tutorial, the language reference and PEP 8, read 17 October 2026. PEP 8 also says "Python disallows mixing tabs and spaces for indentation."
Learning it properly
Fixing one error at midnight is useful. Understanding blocks well enough that the errors stop is better, and that is what our classes aim for.
| Classes | What the student does | What it teaches about indentation |
|---|---|---|
| 1 to 2 | First programs with if and else | A colon opens a block; the block is everything indented under it |
| 3 to 4 | Loops that count and total | Which lines run every time, and which run once after |
| 5 to 6 | Functions with return | Where a function ends, and why a return can end it early |
| 7 to 8 | Nested loops and conditions | Reading three levels at once; the stack walk-through above |
| 9 to 10 | A small project of their choice | Keeping a long file consistent: 4 spaces, no tabs |
| 11 to 12 | Reading other people's code | Explaining a program block by block, out loud |
We teach the concept so a student can solve their own school assignments; we do not write graded work for anyone. For a wider method that covers every kind of bug, see how to debug code, and for errors that happen while a program runs, exception handling in Python.
Where a student is
Find the row that sounds like you. The goal is stage 4.
| Stage | What it looks like |
|---|---|
| 1. Copier | Spacing matches an example, but the student cannot say why |
| 2. Fixer | Can clear an IndentationError by trial, sometimes breaking the logic |
| 3. Reader | Can say which lines belong to which block before running |
| 4. Designer | Plans blocks first, and indentation errors almost never appear |
Indentation errors are a sign your child is writing real Python, not a sign they are bad at it. Every programmer has met them.
Ask your child to explain one block of their code to you. If they can, they are past stage 2.
Read the colon line and the line under it before touching anything. The message is pointing at one of the two.
Pick 4 spaces and never mix in a tab. That one habit removes TabError for good.
The catalogue
Live online, with a regular teacher, in a batch or one to one.
PIE / KID / 01
Turtle drawings, games, first blocks.
Open the syllabusPIE / KID / 02
Nesting you can see, before typed code.
Open the syllabusPIE / KID / 03
Loops and conditions on real maths.
Open the syllabusPIE / TEN / 01
Every block type, then projects.
Open the syllabusPIE / TEN / 02
Nested loops that stay readable.
Open the syllabusPIE / TEN / 03
Notebooks, pandas, clean cells.
Open the syllabusPIE / PRO / 01
PCEP and PCAP, syntax rules included.
Open the syllabusPIE / PRO / 02
Zero to advanced for ages 18 and up.
Open the syllabusPIE / PRO / 03
Java blocks, braces and style.
Open the syllabusHow lessons run
Weekdays or weekends, flexible: choose your batch, or for a very personalised plan choose 1-on-1 at your convenience, weekend mornings or weekdays.
Weekdays
After school in your time zone, in a batch.
Weekends
A calmer slot for longer projects.
1-on-1
Built around your own schedule.
Someone who knows your code.
IDLE, VS Code or a notebook.
We start from what broke.
You solve your own assignments.
From home, coast to coast.
Fifteen to twenty, or just you.
Student work
Programs written by learners who once stared at their first IndentationError too. See more on the student labs page.

AI and ML
An AI nutrition coach that reads what you eat and works you toward a target.

AI and ML
A chatbot that answers mathematics and programming questions, built and deployed by a student.

AI and ML
An assistant that helps a young person recognise unsafe situations online.

Web app
A weather forecasting site with live conditions for any location.
Fees
Python costs nothing to install, and every editor named here has a free version. The fee covers live teaching, billed one month at a time in US dollars, with no semester contract and nothing owed once you stop.
Free first class
USD 0
no card required
Group batch
USD 100
a month, billed in US dollars
One to one
USD 150
a month, billed in US dollars
What families say
Parents' Google reviews, copied exactly.
★★★★★
"The one step solution for my son. Modern Age Coders make learning coding so simple that kids love it. The teachers explain complex concepts clearly with practical exercises and interactive content."
Ria Mukherjee
Parent
★★★★★
"Modern Age Coders has been a game-changer for me. I struggled to grasp IT concepts and coding before joining, but their classes transformed everything. I can now confidently write complex programs with ease."
Samriddha Mondal
Student
★★★★★
"One of the most wonderful education centres out there. Education is not limited to school syllabus but focuses on skill development."
Vansh Agarwal
Student
★★★★★
"My child Dhairya is really enjoying the Modern Age Coders classes. This is his first online class and he eagerly looks forward to it. I can already see his improvement, and the teachers are very cooperative."
Sonam Oswal
Parent of Dhairya
★★★★★
"Modern Age Coders have wonderful teachers who teach in a clear, easy and practical way. The teacher boosts students' confidence and inspires them to learn without hesitation."
Sonu Goyal
Parent
★★★★★
"I highly recommend this computer coding class! The teachers are incredibly knowledgeable and passionate about coding."
Ritu Kedia
Parent
Questions students ask
It means the spaces at the start of a line do not fit the block structure Python expects. The Python documentation describes IndentationError as the base class for syntax errors related to incorrect indentation, and it is a subclass of SyntaxError, so nothing runs until it is fixed.
Find the line ending in a colon that the message names, and indent the line under it by 4 spaces. If the body is not written yet, put pass on an indented line. A comment on its own does not count as a body.
A line starts further right than it should, even though nothing above it opened a block. Move it back to line up with the line before it.
A line stepped back to a column that no earlier line used, so Python cannot tell which block it belongs to. Line it up exactly with the block it should join, usually 4 spaces per level.
It is a subclass of IndentationError, raised when indentation mixes tabs and spaces inconsistently. Convert the whole file to spaces. Running python -m tabnanny on the file shows the line it finds ambiguous.
Spaces. The Python tutorial says to use 4-space indentation and no tabs, and PEP 8, the Python style guide, calls spaces the preferred indentation method.
Colab runs ordinary Python, so the same rules apply inside each cell. The usual cause is pasted code with mixed spacing. Re-indent the whole cell with 4 spaces per level and run that cell again.
No. We teach the concept so you can solve your own assignments, and we never write graded work. In a lesson, a teacher will walk through your error with you until you can fix it yourself.
Weekdays or weekends, flexible. Choose your batch, or for a very personalised plan choose 1-on-1 at your convenience, weekend mornings or weekdays.
The first lesson is free. After that, families pay for one month of live teaching at a time, and the fees section of this page shows the current monthly amount in US dollars.
Elsewhere on this site
More help for US students learning Python.
Every page we have written for US families.
A method for bugs beyond indentation.
Errors that appear while a program runs.
Where a high school freshman can start.
The AP course many students meet first.
Inside a live lesson, step by step.
Python turtle not working? The real errors, the fixes, and how to write text.
Scratch not working? Saving, sign-in, school network and tablet fixes, from the Scratch Help Center.
MakeCode Arcade help: jumping, gravity, tilemap levels and lost projects.
Start here
Send us the error your student is stuck on, or the course they are taking at school. The first lesson works through it together.
Curious how a class runs? Our page on teaching method describes one, and the course list shows each syllabus in full.
WhatsApp us · +91 91233 66161 · connect@modernagecoders.com
Lessons are live on video with teachers based in India, so there is no local center to visit; we schedule around US time zones. WhatsApp is the fastest way to reach us.
A priority demo is a full class of about 45 to 60 minutes. After the class the mentor sends a written skill report and a personal learning roadmap on WhatsApp. If you enrol, the demo fee is adjusted against your first month's fee. Share your demo Order ID with us on WhatsApp and we take it off.
Book a priority demo