
Устранение ошибки «Неожиданный токен» в JSON.parse: практическое руководство по всем возможным причинам
Опубликовано 23 июл. 2026 г.
SyntaxError: Unexpected token X in JSON at position N — одна из самых распространенных ошибок в JavaScript и одна из наименее полезных: она указывает, где парсер прервал работу, но не почему. Вот как на самом деле исправить эту ошибку.
Шаг 1: определите номер позиции
JSON.parse считает символы от начала строки, начиная с 0. Если ваш JSON был получен из переменной, прежде чем предпринимать какие-либо действия, выведите в лог точный фрагмент кода вокруг этой позиции:
try {
JSON.parse(raw);
} catch (e) {
const match = e.message.match(/position (\d+)/);
if (match) {
const pos = Number(match[1]);
console.log(raw.slice(Math.max(0, pos - 20), pos + 20));
}
}
Этот один фрагмент кода решает больше подобных ошибок, чем любой совет по синтаксису JSON, потому что большинство ошибок «неожиданный токен» на самом деле являются ошибки типа «Я не знаю, что на самом деле содержит моя строка» — конечные пробелы после копирования-вставки, лишний символ новой строки из шаблонного литерала или маркер порядка байтов (BOM) в самом начале (позиция 0, токен , который невидим в большинстве редакторов).
7 причин, ранжированных по частоте их возникновения
- Лишняя запятая в конце.
{"a": 1, "b": 2,}— допустима в литералах объектов JS, недопустима в JSON. Запятая перед}или]является самой распространённой причиной. - Одинарные кавычки вместо двойных.
{'a': 1}— это JS, а не JSON. В JSON требуется использовать двойные кавычки как для ключей, так и для строковых значений, без исключений. - Ключи без кавычек.
{a: 1}— опять же, допустимо в JS, недопустимо в JSON. Каждый ключ должен быть заключён в кавычки. - Значение JS, которое не является допустимым JSON.
undefined,NaN, функция или комментарий (// like this) — ни одно из них не существует в спецификации JSON, только в JavaScript. - Двойное кодирование. Вы вызвали
JSON.stringify()дважды или анализируете строку, которая уже является объектом — проверьте с помощьюtypeof raw === 'string'перед вызовом.parse(). - Пустая строка или ответ
undefined. Если запрос завершился с ошибкой без уведомления или вернул пустое тело,JSON.parse("")генерирует исключениеUnexpected end of JSON input— другую, но связанную с этим ошибку; проверьтеresponse.okи запишите исходное тело в журнал перед разбором. - BOM или невидимые символы при копировании-вставке. При вставке JSON из PDF, документа Word или вывода терминала может передаваться BOM или неразрывный пробел, который выглядит идентично обычному символу.
Самый быстрый способ исправления: проверьте данные перед отладкой
Читать необработанные сообщения об ошибках посимвольно — дело медленное. Вставьте точную строку в форматировщик, который выделяет недопустимый символ напрямую, а не угадывает его по номеру позиции — это превращает «где-то около символа 812» в «вот эту конкретную недостающую скобку, прямо здесь» (ссылка приведена ниже).
Когда JSON действительно корректен, но всё равно вызывает ошибку
Если форматировщик подтверждает, что ваш JSON синтаксически корректен, а JSON.parse всё равно выдает ошибку, значит, передаваемая вами строка не является той, которой вы её считаете. Наиболее частая причина: вы вызываете .parse() на объекте Response вместо его разрешённого тела.
// Wrong — parses "[object Response]", not the body
const data = JSON.parse(await fetch(url));
// Right
const data = await (await fetch(url)).json();
// or, if you need the raw text first:
const text = await (await fetch(url)).text();
const data = JSON.parse(text);
Краткое руководство
| Симптом | Вероятная причина |
|---|---|
Unexpected token } |
Лишняя запятая перед закрывающей фигурной скобкой |
Unexpected token ' |
Использование одинарных кавычек вместо двойных |
Unexpected token a (или любая буква) |
Ключ объекта без кавычек |
Unexpected end of JSON input |
Пустая строка, усечённый ответ или незакрытая скобка |
Unexpected token (позиция 0) |
Маркер порядка байтов из скопированного-вставленного или сохраненного в Windows файла |
Ничего из этого не требует запоминания — исправление всегда состоит из одних и тех же трёх шагов: выделить фрагмент вокруг указанной позиции, пропустить его через форматировщик, исправить один символ, на который он указывает.