- Python
JSONDecodeError: Expecting valueの直し方
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) は、JSON として読もうとした文字列が、先頭(0文字目)から JSON ではなかったときのエラーです。 多くの場合、JSON の書き方の間違いではなく、そもそも JSON が来ていません。
char 0 のときに、実際に来ていたもの(確認環境):
| 来ていたもの | 例 | よくある場面 |
|---|---|---|
| 空の文字列 | '' |
API が 204(No Content)を返した、ファイルが空 |
| HTML | <!DOCTYPE html>... |
404・500 のエラーページ、ログイン画面へのリダイレクト |
| BOM 付きのファイル | {...} |
Windows のメモ帳・Excel で保存した JSON(メッセージは Unexpected UTF-8 BOM) |
まず、読もうとした中身を表示します。
print(repr(text[:200])) # 文字列なら
print(r.status_code, r.headers.get('Content-Type'), repr(r.text[:200])) # requests なら
確認環境:Python 3.10・3.12・3.13・3.14、requests 2.34(確認日 2026年10月11日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「JSONDecodeError: Expecting valueの直し方」
エラー位置の読み方
JSONDecodeError: Expecting value: line 1 column 7 (char 6)
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~
何が期待されたか どこで止まったか(行・列・先頭からの文字数)
| 部分 | 意味 |
|---|---|
line 1 column 7 |
1行目の7文字目(1から数える) |
(char 6) |
先頭から数えて6文字目(0から数える) |
char 0 |
先頭の1文字目から JSON ではない |
except json.JSONDecodeError as e:
print(e.msg, e.lineno, e.colno)
print(repr(e.doc[max(0, e.pos - 20): e.pos + 20])) # 止まった位置の前後
e.doc に読もうとした文字列、e.pos に止まった位置が入っています(Python 公式ドキュメント)。前後を表示すると、どこが間違っているかがすぐ分かります。
メッセージ別の原因(確認環境)
| 読んだ文字列 | メッセージ |
|---|---|
''(空) |
Expecting value: line 1 column 1 (char 0) |
' '(空白だけ) |
Expecting value: line 1 column 4 (char 3) |
'<!DOCTYPE html>...' |
Expecting value: line 1 column 1 (char 0) |
"{'a': 1}"(シングルクォート) |
Expecting property name enclosed in double quotes: line 1 column 2 (char 1) |
'{"a": None}'・'{"a": True}'(Python の書き方) |
Expecting value: line 1 column 7 (char 6) |
'{"a": 1,}'(最後にカンマ) |
3.13 以降:Illegal trailing comma before end of object/3.12 以前:Expecting property name ... |
'{"a":1}\n{"a":2}'(1行1つの JSON) |
Extra data: line 2 column 1 (char 8) |
'{"a": 1 "b": 2}'(カンマ抜け) |
Expecting ',' delimiter |
'{"a": "x'(閉じていない) |
Unterminated string starting at |
BOM 付きのファイルを encoding='utf-8' で読む |
Unexpected UTF-8 BOM (decode using utf-8-sig) |
Python 3.13 からは、最後のカンマに Illegal trailing comma という分かりやすいメッセージが出ました。 '{"a": NaN}' は、エラーにならずに nan として読まれました(Python の json モジュールは、既定で NaN を受け付けます)。
requests の r.json() で出るとき
ローカルのサーバーで、いろいろな応答を返して r.json() を呼びました。
| 応答 | status_code | Content-Type | 結果 |
|---|---|---|---|
| 正常な JSON | 200 | application/json | {'a': 1} |
| 404 の HTML | 404 | text/html | Expecting value: line 1 column 1 (char 0) |
| 204(中身なし) | 204 | なし | Expecting value: line 1 column 1 (char 0) |
| ログイン画面へリダイレクト | 200(r.history に 302) |
text/html | Expecting value: line 1 column 1 (char 0) |
リダイレクトの例では、status_code が 200 なのに HTML が返っていました。 認証の期限切れで、ログイン画面に飛ばされた形です。r.history に 302 が残っていることで気づけます。
r = requests.get(url, timeout=10)
r.raise_for_status() # 4xx・5xx なら HTTPError
if 'application/json' not in r.headers.get('Content-Type', ''):
raise ValueError(f'JSON ではない応答: {r.status_code} {r.text[:200]!r}')
data = r.json()
requests の公式ドキュメントでも、r.json() が成功しても通信の成功とは限らないので、raise_for_status() か status_code で確かめるよう書かれています。
落とし穴:except json.JSONDecodeError で捕まらない
>>> isinstance(e, json.JSONDecodeError) # r.json() で出た例外
False
確認環境(simplejson が入っている環境)では、r.json() の例外は、標準の json.JSONDecodeError の仲間ではなく、except json.JSONDecodeError: では捕まりませんでした。 requests の例外は、入っている JSON のライブラリによって元のクラスが変わります。
| 書き方 | 捕まるか |
|---|---|
except json.JSONDecodeError: |
環境によって捕まらない |
except requests.exceptions.JSONDecodeError: |
捕まる(requests の公式ドキュメントの書き方) |
except ValueError: |
捕まる |
ファイルを読むとき
with open('data.json', encoding='utf-8-sig') as f: # BOM があってもなくても読める
data = json.load(f)
utf-8-sig は、BOM があれば取り除き、無ければそのまま読みました。 Windows で作られた JSON を読む可能性があるなら、utf-8-sig にしておくと安全です。
| ファイルの中身 | 直し方 |
|---|---|
| 空 | 読む前に os.path.getsize() で確かめる |
| 1行1つの JSON(JSON Lines) | for line in f: json.loads(line) |
Python の dict を str() したもの(シングルクォート・None) |
出力する側で json.dumps を使う。受け取ったものは ast.literal_eval で読める |
"{'a': 1, 'b': None}" のような、Python の dict を文字列にしたものは JSON ではありません。 確認環境では ast.literal_eval で読めましたが、本来は出力する側を json.dumps に直します。
確認の手順(チェックリスト)
| 順番 | 確認すること | 方法 |
|---|---|---|
| 1 | 何が来ていたか | repr(text[:200]) |
| 2 | char 0 か |
先頭から JSON でない:空・HTML・BOM |
| 3 | API なら | status_code・Content-Type・r.history |
| 4 | char 0 以外 |
e.doc[e.pos-20:e.pos+20] で前後を見る |
| 5 | 例外の捕まえ方 | requests.exceptions.JSONDecodeError |
| 6 | ファイル | encoding='utf-8-sig'、JSON Lines は1行ずつ |
よくある質問
Q. JavaScript でも同じエラーが出ます。
A. JavaScript の JSON.parse では Unexpected token '<' などのメッセージになります。関連記事の「Unexpected token '<' in JSONの原因と直し方|fetch」で扱っています。
まとめ
char 0は、先頭から JSON ではない。多くは 空・HTML・BOM- まず
repr(text[:200])で中身を見る - API は
status_code・Content-Type・r.history。200 でもログイン画面のことがある except json.JSONDecodeErrorでは、requests の例外を捕まえられない環境がある- シングルクォートは
Expecting property name enclosed in double quotes、最後のカンマは 3.13 からIllegal trailing comma - ファイルは
utf-8-sigで読む
参考・出典
確認日はいずれも 2026年10月11日です。
- Python ドキュメント「json — JSON encoder and decoder」:https://docs.python.org/3/library/json.html
- Requests「Quickstart」(JSON Response Content):https://requests.readthedocs.io/en/latest/user/quickstart/
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「JSONDecodeError: Expecting valueの直し方」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。