Python TabError — Inconsistent Use of Tabs and Spaces
Fix TabError inconsistent use of tabs and spaces by normalizing one file to spaces and configuring your editor to never emit tabs.
Symptoms
- Python raises "TabError: inconsistent use of tabs and spaces in indentation"
- The file runs on one machine but errors on another
- Errors cluster around code copied from a different editor
Possible causes
- Some lines use tabs and others use spaces for the same indentation level
- Editor tabstop differs from Python tab expansion (8 columns)
- A patch or merge introduced one style into a file that used the other
Diagnosis steps
Detect tabs in the file
grep -nP "\t" app.py | headInterpretation
Any hit inside indentation indicates mixed styles; Python 3 refuses to guess.
Expand tabs and recompile
expand -t 4 app.py > app_fixed.py && python -m py_compile app_fixed.pyInterpretation
Expanding to the intended width then compiling confirms the fix before you commit.
Root cause
Python 3 rejects mixing tabs and spaces within the same block because the two have no unambiguous common width. TabError is raised during tokenization as soon as inconsistent indentation is detected.
Fix
Convert the whole file to spaces with expand or a formatter, then add an .editorconfig with indent_style = space and a pre-commit hook that rejects tabs.
Risk note
Converting tabs to spaces changes byte offsets; avoid doing it in the same commit as functional changes to keep diffs reviewable.
Verify the fix
Recompile and run; grep for tabs returns nothing. Run the same file on a second OS to confirm portability.
Symptoms
This debugging guide addresses “Python TabError — Inconsistent Use of Tabs and Spaces”. Start from the symptoms, follow the ordered diagnostics, and confirm each hypothesis before moving on; the fix and verification steps then close the loop.
Observed symptoms include:
- Python raises “TabError: inconsistent use of tabs and spaces in indentation”
- The file runs on one machine but errors on another
- Errors cluster around code copied from a different editor
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: Detect tabs in the file
grep -nP "\t" app.py | head
Any hit inside indentation indicates mixed styles; Python 3 refuses to guess.
Step 2: Expand tabs and recompile
expand -t 4 app.py > app_fixed.py && python -m py_compile app_fixed.py
Expanding to the intended width then compiling confirms the fix before you commit.
Likely contributors, in order of frequency:
- Some lines use tabs and others use spaces for the same indentation level
- Editor tabstop differs from Python tab expansion (8 columns)
- A patch or merge introduced one style into a file that used the other
Root Cause
Python 3 rejects mixing tabs and spaces within the same block because the two have no unambiguous common width. TabError is raised during tokenization as soon as inconsistent indentation is detected.
The Fix
Convert the whole file to spaces with expand or a formatter, then add an .editorconfig with indent_style = space and a pre-commit hook that rejects tabs.
Watch out: Converting tabs to spaces changes byte offsets; avoid doing it in the same commit as functional changes to keep diffs reviewable.
def process(rows):
out = []
for row in rows:
out.append(row.strip())
return out
# One tab-indented line among space-indented lines -> TabError
def broken(rows):
out = []
for row in rows:
out.append(row) # tab here
return out
Verify and Prevent
Recompile and run; grep for tabs returns nothing. Run the same file on a second OS to confirm portability.
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.