Have you ever seen the error “Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0” and had no idea what it meant? I’ve been there.
I thought my JSON was broken but it turned out I was actually loading an HTML error page instead. I’ll show you exactly what caused it, how I fixed it, and share some simple code that helped me build a dynamic JSON loader with error handling and a language switcher. If you’re learning JavaScript or working with fetch()
, this article will save you a lot of confusion.
The Error Show
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
I did. And for a good 30 minutes, I thought something was seriously wrong with my JSON file. I ran it through a validator, checked for typos, and even rewrote it from scratch but the error kept popping up.
Spoiler alert: the problem wasn’t the JSON. Let me walk you through how I figured it out and how you can fix it too. Plus, I’ve added some code to help you practice loading JSON dynamically in your own projects.
What This Error
Let’s break down the actual message:
SyntaxError: Unexpected token < in JSON at position 0
That <
symbol at position 0 means the file you fetched is not JSON at all it’s probably an HTML page. What kind of HTML? Most likely a 404 Not Found page or a server error message.
Here’s what I realized was being returned instead of JSON:
<!DOCTYPE html>
<html>
<head><title>404 Not Found</title></head>
<body><h1>Not Found</h1></body>
</html>
And yeah, trying to parse that as JSON will obviously crash.
What Caused My Error
Here are the three things I checked (and you should too):
- Wrong File Path
I was usingfetch('./fr.json')
, assumingfr.json
was in the same folder. Turns out it wasn’t. - Using
file://
Instead of a Server
I was opening my HTML file directly in the browser without running a server.fetch()
doesn’t work properly with local files this way. - No Server Response
Sometimes the file exists, but the server doesn’t return it correctly due to missing MIME type config or wrong route.
My Original Code
Here’s the code that triggered the error:
handleGetJson(){
console.log("inside handleGetJson");
fetch('./fr.json')
.then((response) => response.json())
.then((messages) => {
console.log("messages");
});
}
Looks okay, right? But it doesn’t handle missing files, invalid responses, or network issues.
The Update Code That Actually Work
handleGetJson() {
console.log("inside handleGetJson");
fetch('./fr.json')
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then((messages) => {
console.log("Loaded messages:", messages);
})
.catch((err) => {
console.error("Error loading JSON:", err);
});
}
This fixed it for me because now I get a useful error if the file isn’t found or if it’s not served correctly.
Practice Functionality Load and Show JSON
Let’s go one step further and display the JSON data in the console or DOM.
Display Message
function displayMessages(messages) {
Object.entries(messages).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
}
Language Switcher
Want to load different languages like fr.json
, en.json
, etc.
function handleGetJsonByLang(langCode) {
console.log(`Loading ${langCode}.json`);
fetch(`./${langCode}.json`)
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then((messages) => {
displayMessages(messages);
})
.catch((err) => {
console.error(`Failed to load ${langCode}.json:`, err);
});
}
You can call this like:
handleGetJsonByLang("fr");
handleGetJsonByLang("en");
Final Fix Use a Real Server
When I switched to using a local server, everything worked. Here’s how I did it:
Using Node.js server
npx http-server .
Or if you’re using React.js:
npm start
Then visit:
http://localhost:3000/fr.json
If the JSON loads in your browser, your fetch will work too!
Final Thoughts
This one little error taught me a big lesson: even the smallest bugs can lead to the biggest confusion if you’re not checking what’s really being returned. Always look at your network responses, check the file paths, and don’t forget to use a development server when dealing with fetch or JSON.
If you’ve ever hit this same issue, I hope this post saved you hours of debugging. And if you’re learning JavaScript or React, try extending this example by creating your own language switcher or a settings panel using JSON-based config files.