Skip to main content

How to Resolve "SyntaxError: 'undefined' is not valid JSON" Error in JavaScript

The SyntaxError: "undefined" is not valid JSON (or the very similar Unexpected token u in JSON at position 0) is a common error that occurs when you try to parse a value with JSON.parse() that is not a valid JSON string. Specifically, it happens when the value you are trying to parse is the JavaScript primitive undefined.

This guide will explain the common scenarios where this error occurs—primarily with API responses and localStorage—and show you how to correctly handle and prevent it.

The Core Problem: JSON.parse() Requires a Valid JSON String

The JSON.parse() function is very strict. It is designed to do one thing: convert a valid JSON string into a JavaScript object or value. The JavaScript primitive undefined is not a string, and when it's coerced into the string "undefined", it is still not a valid JSON document.

Example of problem:

// Problem: Passing a non-string or invalid JSON string to JSON.parse()
let myData = undefined;

// ⛔️ SyntaxError: "undefined" is not valid JSON
let result = JSON.parse(myData);
note

This error tells you that the input to JSON.parse() was invalid. The key to solving it is to find out why your input was undefined.

Scenario 1 (Most Common): Empty or Invalid API Response

This is the most frequent cause of the error. Your code fetches data from an API, expects a JSON response, but receives something else.

Example of problem

async function fetchData() {
try {
let response = await fetch('/api/data');

// If the response body is empty or not JSON, .json() can resolve to undefined or throw.
// Let's assume it gives us an empty body, and we get `undefined`.
let dataText = await response.text(); // Imagine this is an empty string ""

// A library might then pass this to JSON.parse()
let result = JSON.parse(dataText); // ⛔️ This will throw an error on an empty string!
} catch (error) {
console.error("Failed to parse JSON:", error);
}
}

Common Causes:

  • The server responded with an empty body.
  • The server responded with a non-JSON string (like an HTML error page).
  • A network error occurred, and the response object is not what you expect.

Scenario 2: Empty or Non-Existent localStorage Item

Another common cause is trying to parse an item from localStorage that doesn't exist. localStorage.getItem() returns null if the key is not found, and JSON.parse(null) also throws an error.

Example of problem:

// Problem: The 'user-settings' key has never been set.
let settingsString = localStorage.getItem('user-settings');
console.log(settingsString); // Output: null

// ⛔️ SyntaxError: Unexpected token u in JSON at position 0 (if input is undefined)
// or a similar error for `null`.
let settings = JSON.parse(settingsString);

The Solution: A Robust try...catch Parsing Function

Since the input to JSON.parse() is often unpredictable (coming from an external API or browser storage), the best practice is to always wrap your parsing logic in a try...catch block.

This allows you to gracefully handle invalid JSON and provide a default value.

Solution: this reusable function safely parses a string and returns a default value if parsing fails.

/**
* Safely parses a JSON string.
* @param {string} str The string to parse.
* @param {*} defaultValue The value to return if parsing fails.
* @returns {object | Array | any} The parsed object or the default value.
*/
function safeJsonParse(str, defaultValue) {
try {
return JSON.parse(str) || defaultValue;
} catch (error) {
return defaultValue;
}
}

// --- Practical Example with localStorage ---
// 1. Retrieve the item from localStorage (it might be null).
let settingsString = localStorage.getItem('user-settings');

// 2. Safely parse it, providing a default empty object `{}`.
let settings = safeJsonParse(settingsString, {});

console.log(settings); // Output: {} (if the item didn't exist)

This is the most robust and professional way to handle JSON parsing. It prevents your application from crashing due to malformed or missing data.

When using fetch, the .json() method handles parsing for you and will reject the promise if the body is not valid JSON, which you can catch.

fetch('/api/data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json(); // This can throw if the body is not valid JSON
})
.then(data => {
console.log('Success:', data);
})
.catch(error => {
console.error('Fetch error:', error);
});

Conclusion

The "undefined is not valid JSON" error is a signal that your script is attempting to parse an invalid value.

  • The root cause is passing undefined, null, an empty string, or a non-JSON string to JSON.parse().
  • This commonly happens when dealing with API responses that might be empty or errored, or when retrieving a non-existent item from localStorage.
  • The recommended best practice is to wrap all JSON.parse() calls in a try...catch block to handle potential errors gracefully and provide a sensible default value.