Python IndentationError — Unexpected Indent
Resolve IndentationError unexpected indent by matching block indentation to the preceding colon and eliminating mixed tabs inside a single file.
Symptoms
- Python raises "IndentationError: unexpected indent" pointing at one line
- The highlighted line looks aligned in the editor
- The error appears after pasting code from another source
Possible causes
- A line is indented although the previous line did not open a block
- The file mixes tabs and spaces so visual alignment differs from logical indentation
- An editor auto-indent inserted indentation after a comment or blank line
Diagnosis steps
Show whitespace and offending line
python -c "import sys; [print(i, repr(l)) for i,l in enumerate(open('app.py'),1) if l.startswith(' ')]" | headInterpretation
repr output makes tabs visible as \t, exposing mixed indentation that looks aligned on screen.
Compile to locate the first bad line
python -m py_compile app.pyInterpretation
The reported line and caret pinpoint the first logical inconsistency; fix it and recompile.
Root cause
Python derives block structure from indentation alone. An unexpected indent is any indentation that does not follow a colon-terminated block opener, and inconsistent tabs/spaces make the parser see indentation that differs from what the editor renders.
Fix
Indent strictly with spaces (four per level), remove tabs from the file, and make sure every indented line belongs to a block opened by a colon on the previous logical line.
Risk note
Some editors silently convert tabs to spaces; configure a single indentation policy and add an editorconfig to enforce it.
Verify the fix
Recompile with python -m py_compile and run the module; the error should be gone. Add a lint step that rejects tabs so it cannot return.
Symptoms
When you hit “Python IndentationError — Unexpected Indent”, guessing wastes time. The guide below follows evidence: reproduce the symptom, run targeted diagnostics, identify the root cause, apply the fix, and verify it with concrete checks.
Observed symptoms include:
- Python raises “IndentationError: unexpected indent” pointing at one line
- The highlighted line looks aligned in the editor
- The error appears after pasting code from another source
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Show whitespace and offending line
python -c "import sys; [print(i, repr(l)) for i,l in enumerate(open('app.py'),1) if l.startswith(' ')]" | head
repr output makes tabs visible as \t, exposing mixed indentation that looks aligned on screen.
Step 2: Compile to locate the first bad line
python -m py_compile app.py
The reported line and caret pinpoint the first logical inconsistency; fix it and recompile.
Likely contributors, in order of frequency:
- A line is indented although the previous line did not open a block
- The file mixes tabs and spaces so visual alignment differs from logical indentation
- An editor auto-indent inserted indentation after a comment or blank line
Root Cause
Python derives block structure from indentation alone. An unexpected indent is any indentation that does not follow a colon-terminated block opener, and inconsistent tabs/spaces make the parser see indentation that differs from what the editor renders.
The Fix
Indent strictly with spaces (four per level), remove tabs from the file, and make sure every indented line belongs to a block opened by a colon on the previous logical line.
Watch out: Some editors silently convert tabs to spaces; configure a single indentation policy and add an editorconfig to enforce it.
def total(items):
sum_ = 0
for it in items:
sum_ += it # consistent 4-space indent
return sum_
# Mixed tabs/spaces below triggers: IndentationError: unexpected indent
def bad(items):
total_ = 0
for it in items: # tab instead of spaces
total_ += it
return total_
Verify and Prevent
Recompile with python -m py_compile and run the module; the error should be gone. Add a lint step that rejects tabs so it cannot return.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.