IndentationError: Expected an Indented Block — Why It Happens and How to Fix It
Getting “IndentationError: expected an indented block” in Python? This guide explains every cause with clear examples and fixes so you can get back to coding fast.
Python is one of the few languages where whitespace is part of the syntax. That’s a feature, not a bug, but it means errors like IndentationError: expected an indented block show up more often than they do in languages that use curly braces. If you’re staring at this error right now, something in your code structure is telling Python to expect an indented block of code that isn’t there. This post walks through every cause and the exact fix for each one.
What Python Means by “Expected an Indented Block”
Python uses indentation to define code blocks. After a colon at the end of a line (following if, for, while, def, class, with, try, except, and similar keywords), Python expects at least one indented line of code to follow.
If that indented line is missing, Python raises:
IndentationError: expected an indented block
It’s telling you: “I saw a colon, I’m waiting for a block, but there’s nothing there.”
The error includes a line number pointing to where Python lost track. That line number usually points to the line after the colon, or sometimes the next non-empty line in the file.
The Most Common Causes
1. An Empty Function or Class Body
This is the most frequent trigger. You define a function or class but haven’t written the body yet:
def greet():
print("Hello")
Python reads def greet():, expects an indented block, and finds print("Hello") at the same indentation level instead. That’s the error.
The fix depends on what you want:
If the function is a placeholder, use pass:
def greet():
pass
print("Hello")
pass is Python’s way of saying “this block intentionally has no code.” It satisfies the syntax requirement without doing anything.
If you meant to write the body, write it:
def greet():
print("Hello")
2. An Empty if, for, while, or with Block
The same pattern applies to any statement that ends with a colon:
for item in items:
process(item)
if condition:
do_something()
Both raise IndentationError: expected an indented block. Fix them the same way: add pass as a placeholder or add the actual code indented under the block:
for item in items:
process(item)
if condition:
do_something()
3. A Comment Where Code Should Be
A lot of developers hit this one when they stub out code with a comment:
def calculate():
# TODO: implement this later
result = calculate()
Python does not treat comments as code. The comment line doesn’t count as an indented block. The function body is effectively empty, and Python raises the error.
Fix: add pass along with the comment:
def calculate():
# TODO: implement this later
pass
Now the function has a real statement in its body and the comment explains what’s coming.
4. An Empty try or except Block
Error handling blocks follow the same rule:
try:
except ValueError:
print("Invalid value")
The try block has nothing in it. Fix:
try:
result = int(user_input)
except ValueError:
print("Invalid value")
And the except block itself can’t be empty either without pass:
try:
result = int(user_input)
except ValueError:
pass # Silently ignore invalid input
5. An Empty Class Body
Classes need at least one statement in their body too:
class User:
class Admin(User):
pass
The User class has no body. Fix:
class User:
pass
class Admin(User):
pass
The Tabs vs Spaces Problem
Sometimes the error fires even when your code looks perfectly indented. You can see indentation there. Python still complains.
This almost always means you have a mix of tabs and spaces. Python 3 does not allow mixed indentation. A tab character and four spaces might look identical in your editor but are completely different to the interpreter.
The error message in this case is slightly different:
TabError: inconsistent use of tabs and spaces in indentation
But you can also get IndentationError: expected an indented block if the mixing confuses Python’s block detection.
How to fix it:
In most editors you can show invisible characters (whitespace). Look for tabs appearing as arrows or different-width markers compared to spaces.
In VS Code: View > Render Whitespace, or click the spaces/tabs indicator in the bottom status bar to convert all tabs to spaces.
From the command line, Python’s tabnanny module checks for mixed indentation:
python -m tabnanny your_script.py
The safest approach going forward: configure your editor to always insert spaces when you press Tab, and set the indentation width to 4 spaces (the Python standard per PEP 8).
The Blank Line Problem in Some Editors
Some editors insert a blank line after a function or class definition automatically. If that blank line is between the def line and the function body, it can confuse the parser in certain contexts.
More often, the issue is that the function body is separated from the definition by a completely blank (or whitespace-only) line:
def process():
return True
The blank line between def process(): and return True doesn’t always trigger the error (Python can handle some blank lines in blocks), but in certain contexts, especially in interactive shells like the Python REPL, pressing Enter twice after the colon closes the block before you’ve added any code.
In the REPL specifically, this is common:
>>> def greet():
...
>>>
Pressing Enter twice on a blank line in the REPL tells Python you’re done with the block. If you haven’t typed anything in it yet, you get the IndentationError. The fix in the REPL is to type your indented code on the very next line without leaving a blank line first.
How to Read the Error Traceback
When Python throws IndentationError: expected an indented block, the traceback looks like this:
File "script.py", line 5
result = calculate()
^
IndentationError: expected an indented block after function definition on line 3
Modern Python (3.10 and later) gives you a more descriptive message that tells you exactly what kind of block it expected and on which line the definition was. Older versions just give you the line number and the caret pointing at the problem.
The line Python points to is not always the line with the actual mistake. Often the error is on the line before, where the colon is. If Python says line 5 is the problem, look at line 4 to see if there’s a def, if, for, or similar statement ending in a colon with nothing valid after it.
Quick Fix Checklist
Run through these when you see IndentationError: expected an indented block:
- Find the line with the colon that precedes the error line (
def,class,if,for,while,with,try,except) - Check what follows it. Is there an indented line of actual code? Or is the next line at the same indentation level?
- If the body is intentionally empty, add
passas a placeholder - If there’s only a comment, add
passbelow the comment - Check for mixed tabs and spaces using your editor’s whitespace visibility setting or
python -m tabnanny - In the REPL, make sure you type the function body before pressing Enter twice
Using pass the Right Way
pass is not a workaround or a hack. It’s an official Python keyword designed for exactly this situation. You’ll find it throughout production Python code in:
- Abstract base class method stubs
- Exception handlers that intentionally swallow errors
- Placeholder classes during rapid development
- Minimum viable implementations waiting to be filled in
class BaseProcessor:
def process(self, data):
pass # Subclasses must implement this
def validate(self, data):
pass # Subclasses must implement this
There’s nothing wrong with shipping code that has pass in it, as long as the intent is clear. Combine it with a comment explaining why the block is empty and you’re fine.
Python’s indentation rules and the errors they produce are part of what makes the language readable once you’re used to them. The same structural clarity that causes IndentationError: expected an indented block also makes Python code easier to follow at a glance compared to languages with more ambiguous block syntax. If you’re building up your Python skills more broadly, getting comfortable with the language’s structure connects well to learning Python for data work and understanding how Python fits into larger analytics pipelines. Solid fundamentals like handling indentation correctly also reduce bugs in automated scripts and pipelines, which is something that comes up consistently in software quality discussions.
Key Takeaways
IndentationError: expected an indented blockmeans Python found a colon at the end of a line with no indented code following it- The most common cause is an empty function, class, loop, conditional, or try/except block
- Fix empty blocks with
pass, which is a valid Python statement that does nothing - Comments do not count as code; a comment alone in a block still needs
passalongside it - Mixed tabs and spaces cause related indentation errors; configure your editor to use spaces only
- In the Python REPL, don’t press Enter twice before typing the function body
- The line number in the error message points to where Python got confused, not always where you made the mistake; look at the line before it for the colon
Once you understand that Python treats indentation as structure, this error stops being confusing and becomes easy to spot and fix in under a minute.