JSON 尾隨逗號是什麼
尾隨逗號(trailing comma)是物件或陣列的最後一個元素之後、結尾括號 } 或 ] 前方殘留的逗號。標準 JSON(RFC 8259)不允許這種寫法,嚴格的解析器會以 Unexpected token } 或 Expecting property name enclosed in double quotes 之類的錯誤拒絕整個檔案。修法就是刪掉那一個逗號。
這篇文章只講尾隨逗號(,)的問題,不談 // 或 /* */ 註解。JSON 註解是另一篇主題,詳見 JSON 註解方式。這裡專注於:為什麼會報錯、怎麼定位、怎麼修、以及 JSON5 和 JSONC 的差異在哪裡。
在瀏覽器中直接修
如果你只想盡快讓錯誤消失,不需要手動數字符。
- 開啟 JSON 格式化器
- 把解析失敗的 JSON 貼上
- 讀取顯示的錯誤行號。它指向多餘逗號後面的那個結尾括號
- 刪掉該
}或]前方緊鄰的逗號,再按一次執行 - 從輸出區複製整理好的 JSON
格式化全程在瀏覽器中執行。你貼上的 JSON 不會被上傳、記錄或儲存。處理 API 回應或包含內部資料的設定檔案時,這一點很重要。


修前與修後
尾隨逗號出現的位置有兩種:物件和陣列。以下逐一比較。
物件的尾隨逗號:
{
"name": "Aoi",
"role": "Engineer",
}
{
"name": "Aoi",
"role": "Engineer"
}
陣列的尾隨逗號:
[
"red",
"green",
"blue",
]
[
"red",
"green",
"blue"
]
巢狀結構中,內側物件或陣列也可能藏著尾隨逗號:
{
"tags": ["a", "b",],
"meta": {
"active": true,
}
}
{
"tags": ["a", "b"],
"meta": {
"active": true
}
}
不管哪種情況,修法都一樣:把最後一個值與結尾括號之間的逗號刪掉。值本身沒有問題。
你會看到的錯誤訊息
同樣的尾隨逗號,不同語言的解析器用詞不同。
瀏覽器與 Node.js(V8)的 JSON.parse:
SyntaxError: Unexpected token } in JSON at position 42
SyntaxError: Expected double-quoted property name in JSON at position 42
Python 的 json.loads:
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 4 column 1 (char 42)
共同點是:解析器讀到逗號後期待下一個值或鍵,結果等來的卻是結尾括號。大多數解析器回報的位置或行號是結尾括號 } / ] 的位置,所以該刪的逗號在上一行(Python 是例外,它指向逗號本身,後面的表格會看到)。
把同一份輸入實際餵給五種解析器,可以看到位置標示的差異有多大(實測:scripts/benchmarks/json-trailing-comma/,2026-08-17,Node.js v26.7.0 / Python 3.14.6 / jq 1.7.1-apple / json5 2.2.3 / jsonc-parser 3.3.1)。輸入是以下多行物件:
{
"a": 1,
"b": 2,
}
| 解析器 | 尾隨逗號的處理方式 |
|---|---|
V8 (Node.js) JSON.parse | 拒絕。Expected double-quoted property name in JSON at position 22 (line 4 column 1) |
Python json.loads | 拒絕。Illegal trailing comma before end of object: line 3 column 9 (char 20) |
| jq | 拒絕。jq: parse error: Expected another key-value pair at line 4, column 1 |
| JSON5 | 接受(無錯誤) |
| jsonc-parser | 拒絕。PropertyNameExpected at offset 22; ValueExpected at offset 22 |
位置標示因解析器而異。V8 和 jsonc-parser 指向結尾括號的位置(offset 22 / line 4 column 1),jq 指向括號所在的行,只有 Python 指向逗號本身(line 3 column 9)。
如果錯誤訊息出現了卻找不到逗號在哪,貼到 JSON 格式化器 就會標示出對應行。各種 JSON 解析錯誤的原因與修法,詳見 JSON 解析錯誤的原因與修法。
為什麼 JSON 禁止尾隨逗號
RFC 8259在新分頁中開啟 定義逗號是值與值之間的分隔符(separator),不是每個值之後的終止符(terminator)。Section 2 的文法將陣列定義為「逗號分隔的值序列」、物件定義為「逗號分隔的成員序列」,最後一個值之後不允許再放元素。因此只有空白和結尾括號跟隨的逗號沒有分隔對象,符合規格的解析器必須拒絕它。
這個失誤也因為一個原因特別常出現:JavaScript 的物件與陣列字面量允許尾隨逗號,很多編輯器會照此格式整理 .js 檔案。但 JSON.parse() 讀的是嚴格 JSON 而非 JavaScript。在 .js 檔案中沒問題的文字,一旦被當作 JSON 解析就會失敗。把程式碼中的物件複製到 .json 檔案是尾隨逗號混入的最典型路徑。其他嚴格 JSON 的語法規則,詳見 JSON 格式是什麼。
自動移除尾隨逗號
手動刪一個逗號很快,但如果要處理的是 JSON 產生程式碼或大量檔案,就應該自動化。
用序列化器產生 JSON,不要用字串拼接。JSON.stringify(以及各語言的等效功能)不會輸出尾隨逗號,從源頭避免問題:
const data = { name: "Aoi", role: "Engineer" };
const json = JSON.stringify(data, null, 2);
// 永遠有效 — 絕不會產生尾隨逗號
儲存時自動整理。在 VS Code 中對 .json 檔案執行 Format Document(或 Prettier 的 format-on-save),重排格式的過程會移除尾隨逗號。這是保持手動編輯的設定檔案乾淨最簡單的方法。
正規表示式是最後手段。,\s*([}\]]) 匹配逗號加空白加結尾括號:
const cleaned = source.replace(/,(\s*[}\]])/g, "$1");
const data = JSON.parse(cleaned);
只能當作備用方案。它可能誤傷字串值中的逗號(例如 "a,}"),所以只用在你能掌控的檔案上,處理完用 JSON 格式化器 驗證結果。
解析器選項只負責「接受」,不負責「改寫」。有些函式庫可以容忍尾隨逗號(例如 .NET 的 JsonSerializerOptions.AllowTrailingCommas)。這些選項讓你的程式碼讀檔案不報錯,但不會更改磁碟上的檔案,也不會讓其他嚴格解析器接受它。如果 JSON 要傳給其他服務,還是得把逗號刪掉。
用 Python 批次移除
標準函式庫 json 不接受尾隨逗號,但 json5 套件可以按 JSON5 規格(允許尾隨逗號)來解析。走的是真正的解析器,不像正規表示式可能誤碰字串值中的 ,}:
# pip install json5
import json, json5
with open("broken.json") as f:
data = json5.load(f)
with open("fixed.json", "w") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
用 Node.js 批次移除
用 npm 的 json5 套件讀入,再用標準 JSON.stringify 寫回:
// npm install json5
import JSON5 from "json5";
import fs from "node:fs";
const data = JSON5.parse(fs.readFileSync("broken.json", "utf8"));
fs.writeFileSync("fixed.json", JSON.stringify(data, null, 2));
用 sed 一次處理多個檔案
CI 管線或 shell 腳本要一次清理大量檔案時,sed 最方便。但有前述正規表示式的誤傷風險,處理後務必加上解析驗證:
sed -E 's/,[[:space:]]*([}\]])/\1/g' broken.json > fixed.json
python3 -c "import json; json.load(open('fixed.json'))" # 驗證
jq 修不了的原因
jq 的解析器是嚴格的,包含尾隨逗號的輸入它直接拒絕。jq . broken.json 不會修檔案,而是報錯停止。jq 是用來處理已合法 JSON 的工具,先用上面的方法移除逗號,再用 jq 做後續加工。
避免尾隨逗號再次出現
修好一個檔案不代表下一個不會再犯。以下幾道防線可以早抓:
- 編輯器:VS Code 對
.json檔案的尾隨逗號會顯示警告(.jsonc則不顯示)。保持副檔名為.json讓警告維持開啟 - 知道高發位置:尾隨逗號最常出現在手動編輯的設定檔、從
.js原始碼複製過來的 JSON、以及用字串拼接組裝的 JSON。真正序列化器產生的 JSON 是安全的
trailingComma 是從哪來的
儲存時的自動格式化可能是尾隨逗號回流的元兇。Prettier 官方文件與 issue tracker 記載如下:
| 項目 | 內容 | 出處 |
|---|---|---|
| Prettier 預設值 | trailingComma 自 v3.0.0 起預設為 "all",此前是 "es5" | prettier.io/docs/options在新分頁中開啟 |
| VS Code 擴充 | 強制關閉 trailingComma 的是 VS Code 擴充本身而非 Prettier 核心,且只在解析器為 json 時生效 — 變更請求的 issue 已關閉並鎖定 | prettier-vscode#589在新分頁中開啟 |
tsconfig.json | 即使副檔名是 .json,Prettier 核心會推斷此檔為 JSONC,儲存時可能補上尾隨逗號 — 已關閉且標記為不處理 | prettier#15942在新分頁中開啟 |
.jsonc 整體 | 相同的 JSONC 推斷也適用於所有 .jsonc 副檔名的檔案 — issue 仍為 open | prettier#15956在新分頁中開啟 |
在 CI 中加一道 JSON.parse 關卡
JSON 支援的 linter 或建置流程中的 JSON.parse 步驟,可以在尾隨逗號被送到下游服務前截住。不需任何相依的最小寫法:
node -e "JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8'))" config.json
把它掛到 pre-commit hook,或在 CI 中對儲存庫內所有 .json 檔案迴圈執行。手動編輯的設定檔尤其值得加,因為那正是尾隨逗號最容易回流的所在位置。
JSON5 與 JSONC 允許尾隨逗號
如果你為了 diff 乾淨而堅持要保留尾隨逗號,有支援的格式。
- JSON5 是具正式規格的 JSON 超集合,無條件允許尾隨逗號、註解、未加引號的鍵、單引號。實測的五種解析器中唯一
accepted: true且零錯誤的就是它(scripts/benchmarks/json-trailing-comma/) - JSONC(VS Code 使用的「含註解 JSON」)在 JSON 基礎上加了註解。其
jsonc-parser實作採寬容恢復(lenient recovery)策略:遇到尾隨逗號不會丟例外,仍會回傳值,但會把該尾隨逗號記入errors陣列(見上方表格 jsonc-parser 那一行)。回傳值和被正式接受是兩回事,VS Code 設定檔「允許」尾隨逗號指的是前者
要注意的是適用範圍。如果是由理解這些擴充格式的工具讀取的設定檔,完全沒問題。但作為 API 酬載、package.json、或使用嚴格 JSON.parse 的服務,尾隨逗號不合法。
如果你的目標只是乾淨易讀的嚴格 JSON,把結果丟到 JSON 格式化器 確認即可。排版上的具體技巧詳見 JSON 排版線上工具。
常見問題
JSON 能使用尾隨逗號嗎?
不能。RFC 8259 將逗號定義為值與值之間的分隔符,最後一個值之後不允許再放元素。結尾括號 } 或 ] 前的逗號無效,嚴格解析器會以 Unexpected token } 等錯誤拒絕。
怎麼找到並移除尾隨逗號?
把 JSON 貼到 JSON 格式化器。錯誤訊息指向多餘逗號後面的結尾括號,刪掉該行逗號再執行一次即可。要根本防止的話,用 JSON.stringify 產生 JSON,不要手動拼字串。
為什麼 JavaScript 可以用尾隨逗號,JSON 卻不行?
JavaScript 的物件與陣列字面量允許尾隨逗號是語言上的便利設計。JSON 是 JSON.parse 讀取的嚴格資料格式,遵循 RFC 8259,最後一個值之後沒有放元素的規則。同一份文字作為 JS 字面量合法,作為 JSON 則不合法。
尾隨逗號會產生什麼錯誤訊息?
V8 / Node 多數是 Unexpected token }(或 ]),較新 V8 是 Expected double-quoted property name,Python 是 Expecting property name enclosed in double quotes。意思都是:解析器在期待下一個值或鍵的位置看到了結尾括號。
不刪掉、直接設定允許尾隨逗號行不行?
有些解析器可以設定為容忍(例如 .NET 的 AllowTrailingCommas)。但那只是讓讀檔案那端的程式碼不報錯,不會讓檔案本身對其他解析器或傳輸過程有效。要能互通的 JSON,還是得刪掉逗號。
JSON5 中尾隨逗號能正常使用嗎?
可以。JSON5 明確允許尾隨逗號,同時接受註解與未加引號的鍵。適合本地設定檔,但不適用於需要嚴格 RFC 8259 JSON 的 API 資料。
總結
- 尾隨逗號是結尾括號
}/]前方的逗號,標準 JSON 禁止 - 錯誤形式為
Unexpected token }或Expecting property name enclosed in double quotes。回報位置是括號,所以逗號在前一行 - 最快的修法:貼到 JSON 格式化器,讀行號,刪逗號
- 用
JSON.stringify產生並搭配儲存時格式化,可以防止尾隨逗號回流 - JSON5 / JSONC 允許尾隨逗號,但只限理解這些格式的工具有效,API 酬載中不能使用