Python CPython 3.14.3 上でパーサーを実行して確認しました。
Invalid control character at: line L column C (char N)
文字列の中に、U+0020未満の生の文字が含まれています。たいていは本物の改行かタブです。JSONはそれらのエスケープを要求します。Pythonにはそれを受け入れるstrict=Falseというオプションがありますが、そうしてできたドキュメントは、ほかのすべての受け取り側にとって依然として不正なままです。
JSONを貼り付けて、壊れている箇所を正確に確認する
入力
貼り付けたものがブラウザの外に出ることはありません。 connect-src の許可リストにより、これは約束ではなくブラウザによる保証になっています。 自分で確かめる
実際の原因
どれが答えになることが多いか、その順に並べています。
-
01 文字列の中の複数行テキスト
ログの抜粋、SQL、スタックトレース、テンプレートのHTMLは、いずれも本物の改行を含みます。
壊れる例
json.loads('{"sql": "SELECT * FROM t"}')動く例
json.loads('{"sql": "SELECT *\\nFROM t"}') -
02 f文字列や連結で組み立てたJSON
埋め込んだ値はエスケープされません。dictを作ってjson.dumpsを使えば、すべてが正しくエスケープされます。
壊れる例
body = f'{{"note": "{note}"}}'動く例
body = json.dumps({"note": note}) -
03 表計算ソフトからコピーしたタブ
目に見えず、コピー&ペーストをそのまま生き延びます。
ほかのランタイムでの同じ間違い
根本にある問題は同一で、違うのは文言だけです。同僚がこれらのどれかを報告してきたなら、見ているものはあなたと同じです。
| JavaScript (V8) | Bad control character in string literal in JSON at position 11 (line 1 column 12) |
|---|
よくある質問
- strict=Falseは何をしますか?
- json.loads(s, strict=False)は、文字列の中の制御文字を許容します。当座はしのげますが、ドキュメントは不正なJSONのままなので、下流のPython以外のものは今後も拒否します。代わりに、生成している側を直してください。