IndentationError は、Python のインデント(行頭の字下げ)が、文の構造と合っていないときのエラーです。 メッセージは4種類あり、それぞれ直す場所が違います。

メッセージ 意味 直し方
unindent does not match any outer indentation level 字下げを戻した位置が、それまでのどの深さとも一致しない 外側のブロックと同じ深さにそろえる
expected an indented block after 'if' statement on line 2 if・def などの次に、字下げした行が無い 中身を字下げする。空なら pass
unexpected indent 字下げする理由が無い行が字下げされている 字下げを消す
TabError: inconsistent use of tabs and spaces in indentation タブとスペースが混ざり、タブの幅によって意味が変わる タブをスペースにそろえる

見た目ではそろっているのにエラーになるときは、ほとんどがタブとスペースの混在です。エディタの画面では区別できないので、下のコマンドで確かめます。

確認環境:Python 3.10・3.12・3.13・3.14(確認日 2026年10月11日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「IndentationError・TabErrorの直し方|Python」

unindent does not match any outer indentation level

def f(x):
    if x:
        print("a")
      print("b")        # ← 6文字。4(if の深さ)でも 8(print("a") の深さ)でもない
  File "unindent.py", line 4
    print("b")
              ^
IndentationError: unindent does not match any outer indentation level

字下げを戻すときは、それまでに使った深さ(0・4・8)のどれかに、ぴったり戻す必要があります(Python の言語リファレンス)。6文字はどれとも一致しないのでエラーです。^ の位置は、行の最後を指すことがあり、当てになりません。エラーの行の行頭を見ます。

クラスの中のメソッドを1文字ずれて書いたときも、同じエラーになりました。

class A:
    def m(self):
        return 1
   def n(self):          # ← 3文字
        return 2

expected an indented block

def f(x):
    if x:
    print("a")           # ← if の中なのに、if と同じ深さ
IndentationError: expected an indented block after 'if' statement on line 2

Python 3.10 以降は、after 'if' statement on line 2 のように、どの文の中身が無いかを表示します。 3.13 以降は ^^^^^ で範囲も示されました。

中身がコメントだけでも出る

def f():
    # TODO あとで書く

print(1)
IndentationError: expected an indented block after function definition on line 1

コメントは中身として数えられません。 あとで書くつもりの関数・if には、pass を書いておきます。

unexpected indent

x = 1
    print(x)             # ← 字下げする理由が無い
IndentationError: unexpected indent

ほかの場所からコードをコピーして貼り付けたときに多いエラーです。貼り付けた部分全体の字下げを、周りに合わせます。

TabError と、見た目はそろっているのに出るエラー

$ cat -A tab.py
def f(x):$
    if x:$
^Iprint("a")$                ← ^I がタブ
        print("b")$
  File "tab.py", line 3
        print("a")
    ^
TabError: inconsistent use of tabs and spaces in indentation

エディタでタブの幅が4文字だと、3行目は if と同じ深さに、8文字だと4行目と同じ深さに見えます。 Python は、タブの幅によって意味が変わる書き方を、TabError にします(言語リファレンス)。

書き方 結果(確認環境)
タブだけでそろえたファイル 動いた
スペースだけでそろえたファイル 動いた
タブとスペースが混ざり、タブの幅で意味が変わる TabError
タブとスペースが混ざっているが、意味が変わらない エラーにならずに動いた(あとで別の行を足すと出ることがある)

エラーにならない混在もあるので、「今まで動いていたのに、1行足したら TabError」ということが起きます。ファイル全体を、どちらかにそろえておきます。Python のスタイルガイド(PEP 8)では、インデントはスペース4つが推奨です。

タブを見つける方法

コマンド 結果
cat -A ファイル タブが ^I、行末が $ で表示される
grep -nP "\t" *.py タブを含む行を、ファイル名と行番号つきで表示
python -m tabnanny ファイルやフォルダー タブの幅で意味が変わる行を表示(-q でファイル名だけ)
$ python3 -m tabnanny -v tab.py
'tab.py': *** Line 3: trouble in tab city! ***
offending line: '\tprint("a")\n'
indent not greater e.g. at tab sizes 1, 2, 3, 4

$ python3 -m tabnanny p8              ← フォルダーを指定すると、中のファイルをまとめて調べる
p8/tab.py 3 '\tprint("a")\n'
'p8/unindent.py': Indentation Error: unindent does not match any outer indentation level (<tokenize>, line 4)

tabnanny は、TabError になる行だけでなく、IndentationError のファイルも一覧にしました。 プロジェクト全体を一度に調べられます。

タブをスペースに変えるときの注意

$ expand -t 4 tab.py > tab_fixed.py
$ cat -A tab_fixed.py
def f(x):$
    if x:$
    print("a")$                 ← if と同じ深さになった
        print("b")$
$ python3 tab_fixed.py
IndentationError: expected an indented block after 'if' statement on line 2

タブを機械的にスペース4つに変えると、別のエラーになりました。 書いた人の意図(3行目は if の中か)は、ファイルからは分からないためです。変換したあとは、エラーの行を目で見て、意図した深さに直します。エディタの「インデントをスペースに変換」の機能でも同じです。

エディタの設定で防ぐ

設定 内容
Tab キーでスペースを入れる エディタのインデントの設定で、タブではなくスペースを選ぶ
空白の文字を表示する タブとスペースが見分けられる
.editorconfig に indent_style = space チームでそろえる(対応しているエディタで有効)

確認の手順(チェックリスト)

順番 確認すること 方法
1 4種類のどれか unindent・expected・unexpected・TabError
2 エラーの行の行頭 ^ ではなく行頭の字下げを見る
3 見た目はそろっているか そろっていれば、タブの混在を疑う
4 タブを探す cat -A(^I)、python -m tabnanny
5 中身がコメントだけ pass を書く
6 変換したあと 意図した深さかを目で確かめる

よくある質問

Q. Jupyter Notebook や、ブラウザからコピーしたコードで出ます。 A. コピー元によっては、字下げにタブや、ノーブレークスペース(U+00A0)などの特殊な空白が混ざります。特殊な空白は IndentationError ではなく SyntaxError: invalid non-printable character U+00A0 になります。全角スペースの場合も含め、関連記事の「SyntaxError: invalid characterの直し方|全角スペース」で扱っています。

まとめ

  • 4種類のメッセージで、直す場所が違う
  • unindent は、それまでの深さのどれにも戻っていない
  • expected は、中身が無い(コメントだけでも出る。pass を書く)
  • 見た目はそろっているのに出るのは、タブとスペースの混在。cat -A と tabnanny で見つける
  • 混在しても動くことがあるので、1行足して突然出る。スペース4つにそろえる
  • タブを機械的に変換すると、意味が変わることがある。変換後に目で確かめる

参考・出典

確認日はいずれも 2026年10月11日です。

  • Python ドキュメント「Lexical analysis」(Indentation):https://docs.python.org/3/reference/lexical_analysis.html
  • Python ドキュメント「tabnanny — Detection of ambiguous indentation」:https://docs.python.org/3/library/tabnanny.html
  • PEP 8「Style Guide for Python Code」:https://peps.python.org/pep-0008/

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「IndentationError・TabErrorの直し方|Python」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?