Python IndentationError
1IndentationError: overview
An IndentationError means the spaces at the start of a line don't match the block structure Python expected, for example a missing body after a colon or a stray extra indent.
Before this lesson: Python Syntax, Python SyntaxError
2IndentationError: diagram
3IndentationError: explained step by step
An IndentationError means Python found a line whose leading whitespace doesn't match the block structure it expected. Python has no curly braces: the spaces at the start of a line are the structure. A line that ends with a colon opens a block, and every line inside that block must be indented by the same amount.
IndentationError is a special kind of SyntaxError. Python checks the layout of the whole file before it runs a single line, so a bad indent on line 40 stops your program even though lines 1 to 39 were fine. If you want a refresher on the layout rules, see Python syntax.
A small helper to trigger the error safely
A real indentation mistake is raised while the file is being compiled, so you can't catch it with a normal try around the broken line. In this lesson we hand the source code to compile() as a string and catch the error there. That lets every demo run without crashing the page.
def show_error(source):
try:
compile(source, "demo.py", "exec")
print("ok: no indentation problem")
except IndentationError as err:
print(f"{type(err).__name__}: {err.msg} (line {err.lineno})")
show_error("price = 10\nprint(price)\n")
show_error("price = 10\n print(price)\n")How to read an IndentationError traceback
File "main.py", line 3
print("pass")
^
IndentationError: expected an indented block after 'if' statement on line 2
- Read the last line first. It names the exact problem and often the statement that caused it.
- The line number at the top points at the line Python could not accept. For a missing body that is the line after the colon, while the message tells you which header (here line 2) was waiting for it.
- If the code looks perfectly aligned but still fails, the difference is invisible: a tab where you expected spaces. Turn on "show whitespace" in your editor.
Why "expected an indented block" happens
Every header that ends in a colon (if, elif, else, for, while, def, class, try, except, with) needs at least one indented line under it. If the next line starts at the same column, Python reports the header it was waiting on. Compare it with how if statements, for loops and functions are written.
def show_error(source):
try:
compile(source, "demo.py", "exec")
print("ok")
except IndentationError as err:
print(f"{err.msg} (line {err.lineno})")
show_error("score = 80\nif score > 50:\nprint('pass')\n")
show_error("def greet(name):\nprint(name)\n")
show_error("for n in range(3):\nprint(n)\n")
show_error("for n in range(3):\n print(n)\n")The fix is always the same: indent the body by four spaces, or remove the header if you didn't mean to start a block.
An empty block needs pass, not just a comment
A comment is not a statement, so a block that contains only a comment is still empty. When you want to leave a body for later, write pass as a placeholder.
def show_error(source):
try:
compile(source, "demo.py", "exec")
print("ok")
except IndentationError as err:
print(f"{err.msg} (line {err.lineno})")
show_error("def apply_coupon(cart):\n # TODO later\n")
show_error("def apply_coupon(cart):\n pass\n")Why "unexpected indent" happens
The opposite problem: a line is indented but nothing opened a block above it. This usually comes from a stray space at the start of a line, or from pasting a snippet that carried its original indentation with it. A line only gets deeper after a line ending with a colon.
def show_error(source):
try:
compile(source, "demo.py", "exec")
print("ok")
except IndentationError as err:
print(f"{err.msg} (line {err.lineno})")
show_error("total = 5\n tax = 1\n")
show_error("total = 5\ntax = 1\n")Why "unindent does not match any outer indentation level" happens
When a block ends, the next line must return to a column that an earlier line already used. If you step back to a column that was never used, Python can't tell which block you mean. Here the body uses 8 spaces, and the next line uses 4 spaces, which does not match the header's column (0) either.
def show_error(source):
try:
compile(source, "demo.py", "exec")
print("ok")
except IndentationError as err:
print(f"{err.msg} (line {err.lineno})")
show_error("def total():\n a = 1\n b = 2\n")
show_error("def total():\n a = 1\n b = 2\n")This also happens when an else is lined up one or two spaces away from the if it belongs to. Use the same number of spaces for every line at the same level.
Why a tab causes TabError
A tab and four spaces can look identical on screen, but Python treats them as different characters. If one block mixes them, Python raises TabError, a subclass of IndentationError.
mixed = "def total():\n a = 1\n\tb = 2\n"
try:
compile(mixed, "demo.py", "exec")
except IndentationError as err:
print(type(err).__name__ + ":", err.msg)
print(repr(mixed.split("\n")[2]))Printing a line with repr() shows \t for a tab, which makes the invisible visible. Pick four spaces everywhere, as recommended by Python's style guide.
Nested blocks and copy-paste
Each level of nesting adds four more spaces. When you paste code into a loop, the whole pasted chunk must be shifted together, not just its first line. Most editors do this with Tab and Shift+Tab on a selection. Deeper structures such as nested loops make the rule easy to see: the inner body is always four spaces deeper than its header.
Editor settings that prevent these errors
- Turn on show whitespace (dots for spaces, arrows for tabs).
- Set the editor to insert spaces when you press Tab, with a width of 4.
- Use Convert indentation to spaces when a file with tabs arrives.
- Select pasted code and re-indent it as one block instead of fixing lines one at a time.
4IndentationError: syntax
if condition:
body_line_1 # 4 spaces
body_line_2 # same indent for the whole block
if other:
inner_body # 8 spaces: one more level
next_statement # back to column 0 ends the blocks
def placeholder():
pass # empty body needs a statement
5IndentationError: run the example
Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.
broken = (
"total = 0\n"
"for price in [4, 6, 10]:\n"
"total += price\n"
"print(total)\n"
)
try:
compile(broken, "cart.py", "exec")
except IndentationError as err:
print(type(err).__name__ + ":", err.msg)
print("problem is on line", err.lineno)
print("offending text:", err.text.strip())
fixed = broken.replace("\ntotal +=", "\n total +=")
exec(fixed)Expected outputIndentationError: expected an indented block after 'for' statement on line 2
problem is on line 3
offending text: total += price
20
7IndentationError: how the example works
Hover or tap a step to highlight its lines in the example above.
- Line 1-6
brokenis Python source stored in a string. Theforheader on line 2 of that source is followed bytotal += priceat column 0, so the loop has no body. - Line 8-10
compile()checks the source without running it. It fails here, which is exactly what happens when Python loads a script with this mistake. - Line 11
err.msgholds the message without the(file, line)suffix. It names theforstatement waiting for its body. - Line 12-13
err.linenois the line that was not indented (line 3 of the source) anderr.textis its content, so you know where to look. - Line 15-16
replace()adds four spaces in front oftotal +=.exec()runs the repaired code, which sums 4 + 6 + 10 and prints 20.
8IndentationError: common mistakes
Writing the body at the same level as the header
✗ Wrong
score = 80
if score > 50:
print("pass")✓ Right
score = 80
if score > 50:
print("pass")The print line must be indented under the if. Press Tab (set to four spaces) at the start of every line of the body.
Leaving a block with only a comment
✗ Wrong
def send_receipt(order):
# TODO: write this later✓ Right
def send_receipt(order):
# TODO: write this later
passComments don't count as statements. Put pass (or a docstring) in the body until you write the real code.
An extra space before a statement
✗ Wrong
total = 5
tax = 1
print(total + tax)✓ Right
total = 5
tax = 1
print(total + tax)A line may only be indented when the line above it ends with a colon. Remove the stray space.
Dedenting to a level that doesn't exist
✗ Wrong
def total():
a = 1
b = 2✓ Right
def total():
a = 1
b = 2Every line in the same block needs the same indentation. Use four spaces for each level and line up b with a.
Mixing a tab with spaces
✗ Wrong
def total():
a = 1
b = 2✓ Right
def total():
a = 1
b = 2Replace the tab with four spaces. Configure your editor to insert spaces when you press Tab so it can't happen again.
9IndentationError: exercises
Write your answer, then press Check. The checks run in your browser.
1. Indent the function body
Fix the bug Easy ✓ Completedapply_discount(price, percent) should return the price after taking off percent percent, but the file raises an IndentationError. Fix the indentation only, so apply_discount(200, 10) returns 180.0.
def apply_discount(price, percent):
discount = price * percent / 100
return price - discount
print(apply_discount(200, 10))def ...: must start with four spaces, and so must every other line inside the function.def apply_discount(price, percent):
discount = price * percent / 100
return price - discount
print(apply_discount(200, 10))
2. Predict the error messages
Predict the output Easy ✓ CompletedRead the code and type exactly what it prints. Each snippet is compiled, not run, so only the layout matters.
snippets = [
"if True:\n print('a')\n",
"if True:\nprint('a')\n",
"x = 1\n y = 2\n",
"def f():\n pass\n",
]
for number, source in enumerate(snippets, start=1):
try:
compile(source, "snippet", "exec")
print(number, "ok")
except IndentationError as err:
print(number, err.msg)if. Snippet 3 indents a line that follows a normal statement. err.msg is the message without the line number.1 ok
2 expected an indented block after 'if' statement on line 1
3 unexpected indent
4 ok
2 more exercises → 6 more examples
Questions learners ask
Should I use tabs or spaces in Python?
Use four spaces per level. Python 3 refuses to mix tabs and spaces inside one block (TabError), and the official style guide recommends spaces. Set your editor to insert spaces when you press the Tab key and you can forget about the difference.
My code looks correctly indented but I still get an IndentationError. Why?
The difference is probably invisible: a tab among spaces, a non-breaking space pasted from a web page, or trailing whitespace on the line above. Turn on 'show whitespace' in your editor, or print the line with repr() to see the exact characters, then re-indent with spaces.
Is an IndentationError the same as a SyntaxError?
It is a more specific kind. IndentationError is a subclass of SyntaxError, and TabError is a subclass of IndentationError. All three are raised while Python reads the file, before any line runs, so you can't catch them with try/except around the broken line itself.
Further reading
10Next lesson
Up nextPython ValueErrorA ValueError means a function received a value of the correct type but with content it cannot accept, such as int() giv…Related:
Python if, elif and elsePython for LoopsPython FunctionsPython SyntaxError
← Python SyntaxError · All Errors and Exceptions lessons · Practise in the IDE