Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool
Troubleshooting JSON Import/Export Issues
Most JSON import and export failures come down to one of a few causes: the input is not valid JSON, the server returned something other than JSON, the file encoding is wrong, or the data being exported contains JavaScript values that JSON cannot represent. This guide is designed to help you diagnose the exact failure quickly instead of guessing.
If you are debugging a file or API response, start by validating the raw text first. Do not assume the problem is in your app code until you confirm the payload is real JSON.
Start With the Exact Symptom
- `Unexpected token <` near the start: you probably received HTML, often a login page, CDN error page, proxy error, or framework error document instead of JSON.
- `Unexpected token` around a comma, quote, or key name: the input looks like a JavaScript object literal, not strict JSON. Common causes are trailing commas, single quotes, comments, or unquoted keys.
- The data parses but values look wrong: check for duplicate keys, stringified numbers and booleans, unexpected nesting, or a JSON string stored inside JSON.
- `Converting circular structure to JSON`: your export contains self-references or repeated references that `JSON.stringify()` cannot serialize by default.
- `Do not know how to serialize a BigInt`: you must convert `BigInt` values before export, usually to strings.
Common JSON Import Problems
1. The input is not actually valid JSON
JSON is stricter than JavaScript object syntax. It does not allow comments, trailing commas, single-quoted strings, or bare property names. If you copied data from source code, documentation, or a config format like JSON5, that is often the real problem.
Common examples that look close to JSON but fail:
// Invalid: single quotes, trailing comma, and a comment
{
'name': 'Alice',
"age": 30,
}
// Invalid: unquoted key
{
status: "active"
}- Make sure every property name uses double quotes.
- Remove trailing commas from objects and arrays.
- Remove comments. JSON has no comment syntax.
- Escape embedded quotes and control characters inside strings.
- Validate the raw text before you start debugging the parser call.
2. The server returned HTML, not JSON
The most common real-world import issue is not malformed JSON. It is hitting the wrong URL or receiving an HTML response from a redirect, auth wall, proxy, rate limit, or server error page. This usually surfaces as `Unexpected token <` because the response starts with `<!doctype html>` or another HTML tag.
- Inspect the raw response body, not just the exception message.
- Check the HTTP status first. A `200` is not enough if the body is still an HTML page.
- Verify the response `Content-Type` is compatible with JSON, typically `application/json`.
- Confirm you are not being redirected to a login page or anti-bot challenge.
- When using `fetch`, read `response.text()` once while debugging so you can see the real payload.
3. UTF-8 and BOM problems
Current JSON guidance is clear: interoperable JSON exchanged across systems should use UTF-8. The JSON spec also says generators must not add a byte order mark (BOM), although parsers may choose to ignore one. In practice, BOM-prefixed files still break some tools and pipelines, especially when the file came from an editor or export process on Windows.
- Save JSON files as UTF-8.
- Strip a leading BOM if the first character is `\uFEFF`.
- Avoid manual transcoding between UTF-8, UTF-16, and legacy code pages unless required.
- If imported text starts with strange invisible characters or parsing fails at position `0`, inspect the file bytes or reopen the file in a hex-capable editor.
4. Duplicate keys or unexpected structure
A document can be syntactically valid JSON and still behave badly. One example is duplicate object keys. The JSON spec warns that duplicate names make behavior unpredictable because different parsers may keep the last value, reject the payload, or expose the duplicates differently.
{
"mode": "safe",
"mode": "fast"
}- Reject duplicate keys during validation if your parser can detect them.
- Verify whether numbers, booleans, and nulls arrived as strings instead of their real types.
- Check whether the API changed from returning an object to returning an array, or vice versa.
- Watch for nested JSON strings like
{"payload":"{\"id\":1}"}that require an extra parse step.
5. The file format is JSON Lines, not one JSON document
Many exports from data tools are newline-delimited JSON, also called JSON Lines or NDJSON. That format is valid as a sequence of JSON objects, but it is not a single JSON document, so `JSON.parse()` on the entire file will fail.
{"id":1}
{"id":2}
{"id":3}- Parse JSON Lines one line at a time.
- Do not wrap line-delimited records in `JSON.parse()` as one string unless you first convert them.
- If the file is huge, stream it instead of reading the whole thing into memory.
Common JSON Export Problems
1. JavaScript values do not map cleanly to JSON
Export failures often happen because the source data is a JavaScript object, not pure JSON data. The differences matter:
| Value | What `JSON.stringify()` does | Why it causes trouble |
|---|---|---|
| `undefined`, functions, symbols | Dropped from objects; become `null` in arrays | Fields silently disappear or change shape |
| `NaN`, `Infinity`, `-Infinity` | Serialized as `null` | Numeric meaning is lost without an error |
| `BigInt` | Throws | Export fails unless you convert the value first |
| `Date` | Serialized to an ISO string | Consumers may expect a timestamp or timezone-free value instead |
- Normalize the data shape before export instead of trusting raw app state.
- Convert `BigInt` intentionally, usually to strings, so precision is preserved.
- Decide whether non-finite numbers should become `null`, strings, or trigger a validation error.
- Do not assume dates round-trip exactly unless the consumer expects ISO 8601 strings.
2. Circular references break serialization
Objects that reference themselves, directly or indirectly, cause `JSON.stringify()` to throw. This is common with ORM entities, DOM-related objects, caches, graph structures, and application state trees.
- Export only the fields you actually need instead of serializing rich runtime objects.
- Use a replacer if you need to prune cycles or replace them with a marker.
- For debugging, serialize a projected copy rather than mutating the original object.
3. Double-encoded payloads
A frequent export bug is serializing an already serialized string. That creates JSON that contains a JSON string instead of the original object.
// Wrong: payload becomes a quoted JSON string const body = JSON.stringify(JSON.stringify(payload)); // Right: payload becomes one JSON document const body = JSON.stringify(payload);
- If an API receives strings where it expects objects, check for accidental double stringification.
- If imported data looks like
"{\"id\":1}", you probably need one parse step before normal use. - When storing JSON in a database, be clear whether the column contains structured JSON or plain text.
4. File download or API transport issues
Sometimes the JSON string itself is fine, but the handoff is wrong. The file may be saved with the wrong extension, served with the wrong MIME type, truncated mid-write, or sent to an API without the expected request headers.
- For HTTP requests, send `Content-Type: application/json` when the body is JSON.
- For downloads, use a `.json` filename and a JSON-compatible MIME type.
- Check for partial writes when files are generated on the server or in background jobs.
- Inspect the exact bytes if the file opens incorrectly after download.
Practical Code Snippets
Parse imported text more defensively
function parseJsonSafely(raw: string) {
const withoutBom = raw.replace(/^\uFEFF/, "");
const trimmed = withoutBom.trimStart();
if (trimmed.startsWith("<")) {
throw new Error("Expected JSON but received HTML or another non-JSON response.");
}
try {
return JSON.parse(withoutBom);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error(`Invalid JSON: ${message}`);
}
}Stringify data without crashing on common export issues
function safeStringify(value: unknown) {
const seen = new WeakSet<object>();
return JSON.stringify(
value,
(_key, current) => {
if (typeof current === "bigint") {
return current.toString();
}
if (typeof current === "number" && !Number.isFinite(current)) {
return null;
}
if (
current === undefined ||
typeof current === "function" ||
typeof current === "symbol"
) {
return null;
}
if (current && typeof current === "object") {
if (seen.has(current)) {
return "[Circular]";
}
seen.add(current);
}
return current;
},
2,
);
}Recommended Troubleshooting Order
- Look at the raw input or raw HTTP response before parsing.
- Validate that the text is strict JSON, not a JavaScript literal or HTML page.
- Check encoding, especially BOM and non-UTF-8 source files.
- Confirm the data shape matches what your code expects.
- Before export, normalize unsupported JavaScript values and remove circular references.
- Verify the final transport step: headers, MIME type, filename, and whether you accidentally stringified twice.
If you are using an offline JSON formatter or validator, paste the raw payload into it before changing application code. A validator will usually tell you faster whether the problem is syntax, structure, or a non-JSON response masquerading as JSON.
Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool