How to fix Unexpected token ) in JSON in React
The "Unexpected token ) in JSON" error occurs when your React application attempts to parse invalid JSON data. This typically happens when fetching data from an API and trying to parse the response, but the response is not valid JSON—often containing extra characters, syntax errors, or non-JSON content like HTML error pages.
Quick fix
Fixes Unexpected token ) in JSON
function MyComponent() {
useEffect(() => {
fetch('/api/data')
.then(response => {
// Log the entire response
console.log('Status:', response.status);
console.log('Content-Type:', response.headers.get('content-type'));
// Log the response text before parsing as JSON
return response.text();
})
.then(text => {
console.log('Response text:', text);
try {
const data = JSON.parse(text);
console.log('Parsed data:', data);
} catch (error) {
console.error('JSON parse error:', error);
console.error('Failed to parse:', text);
}
})
.catch(error => console.error('Fetch error:', error));
}, []);
return <div>Loading...</div>;
}- Log the response before parsing to inspect actual content
- Check the HTTP status code before parsing
- Verify the API endpoint URL is correct
- Add proper error handling with try-catch
function MyComponent() {useEffect(() => {fetch('/api/data').then(response => {// Log the entire responseconsole.log('Status:', response.status);console.log('Content-Type:', response.headers.get('content-type'));// Log the response text before parsing as JSONreturn response.text();}).then(text => {console.log('Response text:', text);try {const data = JSON.parse(text);console.log('Parsed data:', data);} catch (error) {console.error('JSON parse error:', error);console.error('Failed to parse:', text);}}).catch(error => console.error('Fetch error:', error));}, []);return <div>Loading...</div>;}Unexpected token ) in JSON
What this error means
The "Unexpected token ) in JSON" error is thrown by JavaScript's JSON.parse() method when it encounters malformed JSON. A closing parenthesis ) is not a valid JSON character outside of a string literal. This error appears when your React component tries to parse the response from a fetch request or API call using .json() or JSON.parse(), but the content is not valid JSON. In React applications, this commonly happens when: - An API endpoint returns an error page (HTML) instead of JSON - The server response includes unexpected characters or formatting - The JSON is missing commas, has trailing commas, or has unescaped characters - The API returns a 5xx server error with an HTML error page instead of JSON - Network proxies or middleware intercept and modify the response When JSON.parse() encounters the closing parenthesis character, it doesn't know what to do with it because parentheses are not valid JSON syntax. The JSON specification only allows objects ({}), arrays ([]), strings (""), numbers, booleans (true/false), and null.
Typical symptoms
- Browser console error: "Uncaught SyntaxError: Unexpected token ) in JSON at position X"
- fetch() call succeeds but .json() parsing fails
- API response appears to work but JSON parsing throws an error
- Error occurs inconsistently depending on API response
- Console shows partial or corrupted JSON data before the error
- Application crashes when trying to parse API responses
- Network tab shows 200 OK status but response content is not JSON
Common causes
- API returns HTML error page (like 404 or 500 error page) instead of JSON response
- API endpoint is down or misconfigured and returns an error page
- Incorrect API URL pointing to a non-API endpoint
- Response headers do not indicate Content-Type: application/json
- JSON contains unescaped characters or syntax errors
- API response includes extra closing parenthesis or brackets
- Network proxy or middleware is modifying the response body
- Server sends response with incorrect encoding
- Mixed content: API returns JSON with HTML markup or additional text
- Empty response body or response with only whitespace being parsed as JSON
How to fix "Unexpected token ) in JSON"
Before calling .json() on the response, log the raw response to see what you're actually receiving:
function MyComponent() {
useEffect(() => {
fetch('/api/data')
.then(response => {
// Log the entire response
console.log('Status:', response.status);
console.log('Content-Type:', response.headers.get('content-type'));
// Log the response text before parsing as JSON
return response.text();
})
.then(text => {
console.log('Response text:', text);
try {
const data = JSON.parse(text);
console.log('Parsed data:', data);
} catch (error) {
console.error('JSON parse error:', error);
console.error('Failed to parse:', text);
}
})
.catch(error => console.error('Fetch error:', error));
}, []);
return <div>Loading...</div>;
}This will show you exactly what the API is returning. If you see HTML tags, an error message, or extra characters, that's the problem.
Many APIs return error messages as HTML when something goes wrong. Check the response status and only parse as JSON on success:
fetch('/api/data')
.then(response => {
if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
}
return response.json();
})
.then(data => {
console.log('Success:', data);
})
.catch(error => {
console.error('Error:', error);
});The response.ok property is true for status codes 200-299. If the status is 4xx or 5xx, the server might return HTML instead of JSON.
Double-check that you're calling the correct endpoint. Common mistakes include:
// ❌ Wrong - points to HTML page instead of API
fetch('/api-docs') // This might return HTML documentation
.then(r => r.json())
.catch(e => console.error(e));
// ✅ Correct - points to actual data endpoint
fetch('/api/data')
.then(r => r.json())
.then(data => console.log(data));
// ✅ Check that API route exists in your backend
// For Next.js, verify you have: app/api/data/route.ts or pages/api/data.js
// For Express: ensure app.get('/api/data', ...) existsTest the endpoint directly in your browser's address bar to see what it returns. If you see JSON in the browser, the endpoint is correct. If you see an error page, the endpoint is wrong.
Wrap JSON parsing in a try-catch block to handle malformed JSON gracefully:
async function fetchData() {
try {
const response = await fetch('/api/data');
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
if (error instanceof SyntaxError) {
console.error('Invalid JSON response:', error);
// The response was not valid JSON
} else {
console.error('Fetch error:', error);
}
return null;
}
}
function MyComponent() {
const [data, setData] = useState(null);
useEffect(() => {
fetchData().then(setData);
}, []);
return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
}This approach safely handles JSON parsing errors without crashing your component.
Check that the API is setting the correct Content-Type header:
fetch('/api/data')
.then(response => {
const contentType = response.headers.get('content-type');
console.log('Content-Type:', contentType);
if (!contentType || !contentType.includes('application/json')) {
console.warn('Response is not JSON:', contentType);
return response.text(); // Return as plain text instead
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error(error));If the server isn't setting Content-Type: application/json, the response might contain HTML or other non-JSON content.
If using a proxy or API gateway, it might be intercepting and modifying responses. Verify your proxy configuration:
// In your package.json (for Create React App)
{
"proxy": "http://localhost:5000"
}
// Or configure in setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
})
);
};Make sure your proxy correctly forwards JSON responses without modification.
Test your API endpoint outside of your React app to ensure it returns valid JSON:
# Using curl
curl -v http://localhost:3000/api/data
# Check the response - it should start with { or [
# Not with <html>, error messages, or other textYou can also use Postman or Insomnia to test API responses. This isolates whether the problem is in your React code or in the API itself.
If curl returns HTML or an error, the API is misconfigured. If curl returns valid JSON but React still fails, check your fetch call and error handling.
If the API returns an empty response body, JSON.parse() will fail. Handle this edge case:
async function fetchData() {
try {
const response = await fetch('/api/data');
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const text = await response.text();
// Handle empty response
if (!text) {
console.warn('Empty response from server');
return null;
}
return JSON.parse(text);
} catch (error) {
console.error('Error:', error);
return null;
}
}This prevents trying to parse empty strings as JSON, which would throw an error.
Advanced notes
Server-Side Fixes: If you control the API, always return valid JSON with proper headers:
// Express.js example
app.get('/api/data', (req, res) => {
// Always set Content-Type header
res.setHeader('Content-Type', 'application/json');
try {
const data = { message: 'success' };
// Use res.json() instead of manual JSON.stringify
res.json(data);
} catch (error) {
// Return JSON error, not HTML
res.status(500).json({ error: 'Internal server error' });
}
});Debugging in DevTools: Open your browser's Network tab and inspect the failing API call. Click on the request and check the "Response" tab. If you see HTML tags or non-JSON content, that's your problem. The "Headers" tab will show the Content-Type header.
Using JavaScript JSON validator: You can use a JSON validator to check if your response is valid:
function isValidJSON(text) {
try {
JSON.parse(text);
return true;
} catch {
return false;
}
}
const response = await fetch('/api/data');
const text = await response.text();
console.log('Is valid JSON?', isValidJSON(text));API Mocking for Testing: Use libraries like msw (Mock Service Worker) to mock API responses during testing, ensuring you control the JSON format:
import { setupServer } from 'msw/node';
import { rest } from 'msw';
const server = setupServer(
rest.get('/api/data', (req, res, ctx) => {
return res(ctx.json({ message: 'success' }));
})
);
beforeAll(() => server.listen());Content negotiation: If an API can return multiple formats (JSON, XML, CSV), explicitly request JSON:
fetch('/api/data', {
headers: {
'Accept': 'application/json'
}
})
.then(r => r.json())
.catch(e => console.error(e));Frequently asked questions
- What does "Unexpected token ) in JSON" mean?
- parse() method when it encounters malformed JSON. A closing parenthesis ) is not a valid JSON character outside of a string literal. parse(), but the content is not valid JSON.
- How do I fix "Unexpected token ) in JSON"?
- The "Unexpected token ) in JSON" error occurs when your React application attempts to parse invalid JSON data. This typically happens when fetching data from an API and trying to parse the response, but the response is not valid JSON—often containing extra characters, syntax errors, or non-JSON content like HTML error pages.
- What causes "Unexpected token ) in JSON"?
- API returns HTML error page (like 404 or 500 error page) instead of JSON response API endpoint is down or misconfigured and returns an error page Incorrect API URL pointing to a non-API endpoint
- Is the "Unexpected token ) in JSON" error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- 📚React Official Documentation
- 📖MDN: SyntaxError: JSON.parse bad parsing(Official Docs)
- 📖MDN: Fetch API Documentation(Official Docs)
- 📖JSON Official Specification(Official Docs)
- 🐙