What You'll Learn
- The 10 most common JSON mistakes
- How to validate JSON quickly
- How to debug "invalid JSON" API errors
- How to write JSON safely in code
Why This Matters
Sending invalid JSON to an API is the #1 cause of 400 Bad Request errors. The server cannot parse your request body, so it rejects the whole thing. Knowing the common mistakes — and how to validate JSON before sending it — saves hours of debugging.
The 10 Most Common JSON Mistakes
1. Single quotes instead of double quotes
// Invalid
{'name': 'Anita'}
// Valid
{"name": "Anita"}
JavaScript allows single quotes; JSON does not. Always use double quotes for keys and string values.
2. Unquoted keys
// Invalid
{name: "Anita"}
// Valid
{"name": "Anita"}
3. Trailing commas
// Invalid
{"a": 1, "b": 2,}
// Valid
{"a": 1, "b": 2}
The extra comma after the last value is invalid JSON. Many editors highlight this; pay attention.
4. Comments
// Invalid
{
"name": "Anita",
// this is the user's email
"email": "anita@example.com"
}
JSON does not support comments. If you need to document fields, use a separate file or JSONC (a non-standard extension).
5. Wrong boolean capitalization
// Invalid
{"active": True}
{"active": TRUE}
// Valid
{"active": true}
6. Wrong null capitalization
// Invalid
{"phone": Null}
{"phone": NULL}
// Valid
{"phone": null}
7. NaN or Infinity
// Invalid
{"value": NaN}
{"value": Infinity}
// Valid (use null)
{"value": null}
JSON has no representation for NaN or Infinity. Use null and document the meaning separately.
8. Functions or undefined
// Invalid
{"callback": function() { return 1; }}
{"value": undefined}
JSON can only represent data, not code. Functions and undefined are not valid.
9. Unescaped characters in strings
// Invalid (unescaped quote)
{"msg": "She said "hello""}
// Valid
{"msg": "She said \"hello\""}
// Valid (escaped newline)
{"msg": "Line 1\nLine 2"}
Inside a string, escape these characters: \" (quote), \\ (backslash), \n (newline), \t (tab), \r (carriage return).
10. Wrong number format
// Invalid
{"price": 1,000}
{"hex": 0xFF}
// Valid
{"price": 1000}
{"hex": 255}
JSON numbers are plain digits with an optional minus and decimal point. No commas, no hex, no leading zeros (except 0 itself).
How to Validate JSON
Quick online check
Paste your JSON into jsonlint.com. It tells you the exact line and character of any error.
From the command line
# Using Python
echo '{"name":"Anita"}' | python -m json.tool
# Using Node.js
echo '{"name":"Anita"}' | node -e "JSON.parse(require('fs').readFileSync(0))"
# Using jq
echo '{"name":"Anita"}' | jq .
If your JSON is invalid, these tools print an error with the position. If it's valid, they pretty-print it.
In code
// JavaScript
try {
JSON.parse(input);
console.log("Valid JSON");
} catch (e) {
console.log("Invalid JSON:", e.message);
}
# Python
import json
try:
json.loads(input)
print("Valid JSON")
except json.JSONDecodeError as e:
print(f"Invalid JSON: {e}")
Writing JSON Safely in Code
Never build JSON by string concatenation. Use your language's JSON serializer — it handles escaping, quoting, and formatting automatically:
// JavaScript
const payload = JSON.stringify({name: "Anita", email: "anita@example.com"});
// Produces: '{"name":"Anita","email":"anita@example.com"}'
# Python
import json
payload = json.dumps({"name": "Anita", "email": "anita@example.com"})
Debugging "400 Bad Request" Caused by JSON
When the server returns 400 with a message like "Invalid JSON" or "Unexpected token", follow this process:
- Print the exact body you sent. Add
console.log(payload)right before the request. - Validate it. Paste into jsonlint.com or run through
python -m json.tool. - Check for trailing commas and unquoted keys. These are the most common culprits.
- Check the
Content-Typeheader. It must beapplication/jsonif you're sending JSON. - Check for hidden characters. Copy-pasting from Word or PDF can introduce invisible characters.
Common Mistakes
- Building JSON by hand. Use serializers. They never produce invalid JSON.
- Not validating before sending. A 5-second validation check saves a 30-minute debug session.
- Trusting user input as JSON. Always wrap
JSON.parsein try/catch — invalid input should not crash your program. - Forgetting the
Content-Typeheader. Even valid JSON gets rejected if the header is missing or wrong. - Confusing JSON with JavaScript object literals. JS allows many things JSON does not (single quotes, unquoted keys, comments, trailing commas).
Practical Exercise (10 minutes)
Each of these JSON snippets has exactly one error. Find and fix each one:
{'name': 'Anita'}{"a": 1, "b": 2,}{name: "Anita"}{"active": True}{"value": NaN}{"msg": "She said "hi""}{"price": 1,000}
Answers: 1. Use double quotes. 2. Remove trailing comma. 3. Quote the key. 4. Lowercase true. 5. Use null. 6. Escape the inner quotes: "She said \"hi\"". 7. Remove the comma: 1000.
Mini Challenge
Write a JavaScript function that takes any JavaScript object and returns valid JSON. Test it with tricky inputs: an object with a function, a circular reference, undefined values, and NaN. What does JSON.stringify do with each? (Hint: it skips functions and undefined, converts NaN to null, and throws on circular references.)
Key Takeaways
- JSON requires double quotes for keys and strings, no trailing commas, no comments, lowercase true/false/null.
- NaN, Infinity, undefined, and functions are not valid JSON.
- Validate JSON with jsonlint.com,
python -m json.tool, orjq. - Never build JSON by string concatenation. Always use a serializer (
JSON.stringify,json.dumps). - When debugging 400 errors: print the body, validate it, check Content-Type, check for hidden characters.
Previously: Lesson 13 practiced reading complex JSON.
Today: You learned the mistakes that break JSON and how to validate it.
Next: Lesson 15 compares JSON with XML — the older format still used in some APIs.
FAQ
What is JSON5?
JSON5 is a superset of JSON that allows unquoted keys, single quotes, trailing commas, comments, and hex numbers. It is useful for configuration files but not supported by standard API parsers. Stick with standard JSON for API payloads.
Why does JSON.stringify not throw on undefined or functions?
It silently skips them — undefined values are omitted from objects, and function-valued properties are dropped. This is intentional: it makes serialization resilient. To catch these, inspect the output or use a custom replacer function.
Comments
Comments
Post a Comment