IndentationError in Python: where it comes from and how to fix it

IndentationError stops a file before it starts: in Python the offset of each line marks out blocks, so a shaky alignment is no longer a matter of style.
5 min read
Believemy logo

Definition

You write a function, you run the file, and Python refuses to start, talking about an offset. The logic is sound, no name is misspelled: what blocks it is the alignment of the lines. That situation has a name, IndentationError.

It surprises newcomers from other languages most of all. Elsewhere, braces say where a block begins and where it ends, and indentation only makes the whole thing readable. Python removed the braces and handed that job to the offset: leading spaces no longer decorate, they structure.

A badly aligned line therefore does not merely read worse, it becomes impossible to interpret. Python can no longer tell which block it belongs to, so it stops right there.

PYTHON
def average(marks):
# the body should be offset by four spaces
total = sum(marks)
return total / len(marks)

# IndentationError: expected an indented block

This error is a special case of SyntaxError, which decides when the fault gets spotted: while the file is being read, before anything runs. A program holding one therefore does not start at all, even when the offset hides in a branch that would never have been reached.


The three messages and what they mean

Once the error shows up, the question is always the same: where do I start? The traceback is chattier here than usual. It does not just say that an alignment is wrong, it says which one, and there are only three cases.

MessageWhat happened
expected an indented blockA colon announces a block, and nothing below it is offset
unexpected indentA line is offset while no block was waiting for one
unindent does not match any outer indentation levelThe step back lands on no level that was ever opened

The first shows up after a def, an if or a for loop left empty with every intention of filling it later. Python accepts no empty block: a colon always demands an offset line below it. The keyword pass exists for exactly that, holding the place without doing anything.

The second takes a second to repair: a line has taken four spaces of advance while no colon opened a block for it.

The third is more puzzling. It reports a way out of a block that lands between two levels: the body was written at four spaces, the line closing it uses two, and that level was never opened. Guessing would change what the program means, so Python refuses.

Warning

The line number shown is where Python noticed the problem, not always where it was made: on a shaky way out of a block, the guilty line is often the one above. Check the alignment of the whole block before fixing anything.


Mixing spaces and tabs

One cause escapes that reading, and it is the most tiresome of all: the one you cannot see. Two lines can look aligned on screen while one is offset by four spaces and the other by a single tab. The editor draws them at the same width, Python counts different characters and refuses to settle it: it raises a TabError, which inherits from IndentationError.

PYTHON
for line in file:
    clean(line)
	save(line)

# the second line starts with a tab, not with spaces
# TabError: inconsistent use of tabs and spaces in indentation

The story is nearly always the same: the file used to work, then a copy and paste slipped a tab into a run of spaces. Realigning the line by eye gives a result that looks correct and breaks elsewhere, since the tab is still sitting there. Ask your editor instead to convert every tab in the file into spaces.


What makes it go away for good

Fixing the error case by case works, but it comes back the following week. Three editor settings make it go away for good.

Four spaces per level, as the PEP 8 style guide recommends: it is the convention of the whole ecosystem, so the one behind every snippet you will ever copy. The tab key set to insert spaces, which makes the mix impossible. And invisible characters shown, while hunting an offset that refuses to give up.

One habit is worth all the settings: write the block at the moment of writing the line that opens it. An if left without a body, an else bolted on afterwards, a try whose content will come later are the three situations where the offset gets lost. Fixing it takes five seconds while the block is fresh, ten minutes once it runs to twenty lines.


Frequently asked questions

Question

Why does Python enforce indentation?

Because it carries the structure instead of decorating it. In brace languages, badly aligned code stays valid and can lie about what it does: what the eye groups is not what the machine runs. In Python, what is seen is what runs.

Question

Can this error be caught with a try?

No, and that is what separates it from an ordinary exception. It is raised while the file is parsed, therefore before the catching block exists as far as Python is concerned. The file has to be fixed, there is no workaround at all.

Question

My editor shows no error, so why does Python report one?

Because the editor draws a tab and a run of spaces at the same width, which Python does not: you see two aligned lines, it reads two different levels. Turn on invisible characters, or change the tab width of the editor.

Related terms

Discover our python glossary

Browse the terms and definitions most commonly used in development with Python.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.