Error Parsing JSON yang Umum dan Cara Memperbaikinya
JSON.parse() tidak melakukan parsing parsial dan tidak menebak maksud Anda — satu karakter salah tempat di mana pun dalam dokumen berukuran multi-megabyte memunculkan SyntaxError generik yang sama seperti satu karakter salah tempat dalam berkas konfigurasi lima baris. Panduan ini menelusuri error-error yang benar-benar akan Anda temui di V8 (Node.js dan Chrome), apa yang sebenarnya disampaikan masing-masing, dan cara memutuskan antara memperbaikinya manual atau menjalankannya lewat alat repair otomatis.
Mengapa JSON.parse melempar error alih-alih menebak
Object literal JavaScript itu pemaaf: key tanpa kutip, trailing comma, string berkutip tunggal, bahkan komentar — semuanya legal, karena kode sumbernya diurai oleh engine yang sama yang mengurai segalanya. JSON bukan JavaScript — ia tata bahasa yang jauh lebih kecil dan ketat (RFC 8259), dan JSON.parse() menegakkan setiap aturan tata bahasa itu tanpa fallback. Tidak ada JSON yang 'hampir benar'; parser membaca dari kiri ke kanan dan berhenti mati pada token pertama yang tak sesuai tata bahasa di posisi itu.
Itu pilihan desain yang disengaja, bukan keterbatasan: parser JSON yang lunak akan diam-diam menerima dokumen yang berbeda halus di tiap implementasi — persis masalah interoperabilitas yang diciptakan JSON untuk dihindari. Konsekuensinya, pesan error menjadi singkat dan posisional alih-alih semantik — parser memberi tahu di mana tata bahasa patah, bukan apa yang Anda maksud tulis.
Trailing comma
Error JSON paling umum adalah trailing comma yang tersisa dari mengedit object literal JavaScript (yang legal) dan lupa bahwa hal itu tidak legal di JSON.
{
"name": "Alice",
"roles": ["admin", "editor"],
}V8 menolak ini pada closing brace, bukan pada komanya, karena koma itu sendiri adalah tata bahasa yang valid sampai parser mengharapkan property lain dan menemukan `}`. Tergantung versi Node/Chrome Anda, akan muncul sesuatu seperti `Unexpected token '}', "...editor"],\n}"... is not valid JSON` (V8 lebih baru, dengan cuplikan) atau yang lama dan lebih ringkas `Unexpected token } in JSON at position 47`. Bagaimanapun, perbaikannya sama: hapus koma sebelum kurung penutup.
Kutip tunggal dan key tanpa kutip
JSON mewajibkan kutip ganda untuk setiap string dan setiap key — tanpa kecuali. String berkutip tunggal dan key telanjang (tanpa kutip) keduanya sangat umum saat JSON diketik manual atau di-copy-paste dari kode sumber JavaScript.
{ 'name': 'Alice' }
{ name: "Alice" }Kutip tunggal di awal memunculkan sesuatu seperti `Unexpected token ''', "{ 'name'"... is not valid JSON`. Key tanpa kutip sedikit berbeda: V8 modern mengenali bahwa nama property sedang diharapkan dan melaporkan `Expected property name or '}' in JSON at position 2`, alih-alih menyalahkan identifier telanjangnya secara langsung. Bagaimanapun, perbaikannya mekanis — bungkus setiap key dan setiap nilai string dengan kutip ganda.
Newline dan karakter kontrol tanpa escape di dalam string
Newline mentah, tab, atau karakter kontrol lain (apa pun di bawah U+0020) di dalam string JSON adalah ilegal — harus di-escape sebagai `\n`, `\t`, dan seterusnya. Ini paling sering tergigit ketika JSON dibangkitkan dengan naifnya menggabungkan nilai multi-baris (pesan log, cuplikan kode, komentar pengguna) ke dalam string literal tanpa meng-escape-nya lebih dulu.
{
"message": "line one
line two"
}Ini menghasilkan `SyntaxError: Bad control character in string literal in JSON at position 21` — salah satu dari sedikit error JSON yang menyebut masalah sebenarnya alih-alih sekadar token. Perbaikannya adalah meng-escape karakternya alih-alih membiarkannya mentah: `"line one\nline two"`.
Key duplikat, NaN/Infinity/undefined, dan karakter BOM
Tiga mode kegagalan yang lebih senyap, patut dihafal namanya. Pertama, key duplikat dalam object JSON sama sekali bukan parse error — `{ "id": 1, "id": 2 }` berhasil diurai, dan JSON.parse diam-diam menyimpan kemunculan terakhir (`id: 2`) dan membuang yang pertama. RFC 8259 menyatakan nama 'sebaiknya' unik tetapi tidak mewajibkan parser menolak duplikat, jadi ini perilaku sesuai spesifikasi yang mudah lolos dari review, bukan bug di parser Anda.
Kedua, `NaN`, `Infinity`, dan `undefined` semuanya valid di JavaScript tetapi tidak satu pun merupakan token JSON valid — JSON hanya punya `number`, tanpa nilai spesial IEEE-754, dan tidak mengenal `undefined` sama sekali (hanya `null`). `{ "value": NaN }` melempar `Unexpected token 'N', ..."value":NaN}"... is not valid JSON` (atau `Unexpected token N in JSON at position 10` di engine lama). Jika Anda menyerialisasi dari JavaScript, `JSON.stringify` sudah mengonversi `NaN`/`Infinity` menjadi `null` dan membuang nilai `undefined` sepenuhnya — errornya biasanya berarti JSON itu ditulis tangan atau berasal dari sumber non-JS yang mengasumsikan semantik JS.
Ketiga, byte-order-mark UTF-8 (U+FEFF) persis di awal berkas — sering ditambahkan diam-diam oleh editor Windows atau sebagian alat Java/.NET saat menyimpan UTF-8 — merusak `JSON.parse` saat berkas dibaca sebagai string mentah, memunculkan `Unexpected token '\ufeff'... is not valid JSON` di posisi 0. Perhatikan bahwa ini secara spesifik masalah `JSON.parse`-pada-string: `Response.json()` di Fetch API mendekode teks UTF-8 dan membuang BOM di awal sebagai bagian dari dekode itu, jadi byte yang sama yang dilayani lewat HTTP dan dibaca dari disk dengan `fs.readFileSync(path, 'utf8')` bisa berperilaku berbeda.
Membaca posisi, dan kapan memakai alat repair
`position` dalam error JSON.parse adalah offset karakter berindeks nol ke dalam string persis yang Anda berikan, bukan nomor baris — Node (v20+) tambahan menghitung dan menyisipkan `(line X column Y)` untuk kenyamanan, tetapi runtime dan peramban lama hanya memberi offset mentah. Dua hal yang sering menjebak: posisi yang dilaporkan adalah tempat parser menyadari tata bahasanya patah, yang untuk trailing comma atau kurung hilang sering satu token setelah tempat Anda benar-benar keliru; dan jika Anda me-pretty-print JSON agar terbaca tetapi sedang men-debug string minified aslinya, offset-offset itu tidak akan sejajar dengan yang Anda lihat di layar.
Untuk sekali salah sintaks dalam dokumen pendek, memperbaikinya manual begitu posisinya ditemukan lebih cepat daripada alat apa pun — tempel ke validator yang menyorot karakter persisnya alih-alih menghitung offset secara manual. Untuk berkas besar dengan beberapa error tak berhubungan, JSON yang dibangkitkan alat upstream yang buggy, atau JSON yang sudah lewat berkali-kali copy-paste yang merusak, memperbaiki manual tak lagi sebanding waktunya. Itulah saatnya beralih ke yang otomatis: JSON Validator milik JsonForge menunjukkan setiap pelanggaran schema dengan path yang tepat begitu dokumen setidaknya bisa diurai, dan JSON Repair mencoba memperbaiki kesalahan struktural umum (kutip hilang, trailing comma, kurung tak cocok) secara otomatis ketika masukannya terlalu hancur untuk diperbaiki satu error demi satu error.
FAQ
- Mengapa JSON.parse gagal pada berkas yang tampak sepenuhnya baik-baik saja?
- Biang kerah tak terlihat yang paling umum adalah karakter byte-order-mark (BOM) di awal, serta 'smart quotes' atau em-dash yang masuk lewat copy-paste dari pengolah kata, aplikasi chat, atau PDF — keduanya tampak identik dengan kutip ganda biasa atau tanda hubung di kebanyakan font, tetapi merupakan karakter Unicode berbeda yang ditolak JSON.parse. Buka berkasnya di editor yang bisa menampilkan karakter tersembunyi/non-ASCII, atau diff terhadap versi yang diketahui baik.
- Mengapa key duplikat tidak dianggap error?
- Spesifikasi JSON (RFC 8259) menyatakan nama anggota object 'sebaiknya' unik tetapi tidak mewajibkan parser menegakkannya, sehingga perilakunya didefinisikan implementasi. JSON.parse JavaScript diam-diam menyimpan duplikat terakhir dan membuang yang lebih awal; parser di beberapa bahasa lain melempar error, dan sebagian justru menyimpan kemunculan pertama. Jangan pernah mengandalkan perilaku key-duplikat yang konsisten antar-lingkungan.
- Bisakah saya membuat JSON.parse menerima trailing comma atau komentar?
- JSON.parse sendiri tidak — ia mengimplementasikan tata bahasa JSON secara ketat tanpa opsi kelenturan. Jika Anda butuh komentar atau trailing comma, gunakan parser superset JSON seperti JSON5 atau parser yang paham JSONC, atau buang sintaks bermasalah itu sebelum memanggil JSON.parse. Jangan menulis stripping berbasis regex sendiri untuk apa pun di luar skrip sekali-pakai — mudah sekali tak sengaja merusak koma atau kurung yang muncul di dalam nilai string.
- Apa cara tercepat menemukan lokasi persis error dalam berkas besar?
- Jangan menghitung karakter secara manual. Tempel dokumen ke formatter atau validator yang menyorot baris dan kolom persis yang bermasalah — itu mengubah penghitungan manual bermenit-menit menjadi pencarian instan, apalagi begitu berkas cukup besar hingga offset karakter mentah tak berarti bagi manusia.
Coba alat ini
Artikel terkait
Apa itu JSON? Panduan Lengkap untuk Pemula →
JSON (JavaScript Object Notation) adalah format pertukaran data yang ringan, mudah dibaca manusia dan mudah diurai mesin. Pelajari sintaks, tipe data, dan struktur yang menjadi fondasi API modern.
Sejarah JSON: Dari Tahun 2000 hingga Menjadi Standar Industri →
Telusuri JSON dari ide Douglas Crockford tahun 2001, diadopsi oleh Yahoo, hingga menjadi standar ECMA-404 yang menggerakkan 90% API modern.
Panduan Lengkap JSON Schema (Draft 7) →
JSON Schema adalah standar untuk mendeskripsikan dan memvalidasi struktur JSON. Pelajari keyword inti, bangun schema API nyata, dan terapkan praktik terbaik.