Python
JSON
error handling
validation
string parsing

How do I check if a string is valid JSON in Python?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The reliable way to check whether a Python string contains valid JSON is to parse it. JSON validity is defined by syntax, not by regular expressions or quick string checks, so a parser is the only trustworthy answer. In Python, the standard json module already gives you everything you need.

Parse the String with json.loads

json.loads takes a string and converts it into normal Python objects. If the string is valid JSON, you get back a dict, list, str, int, float, bool, or None. If the string is invalid, Python raises json.JSONDecodeError.

python
1import json
2
3payload = '{"name": "Ada", "languages": ["Python", "C"]}'
4
5data = json.loads(payload)
6print(type(data))
7print(data["name"])

Output:

text
<class 'dict'>
Ada

That means "is this valid JSON?" is really "can json.loads parse it without throwing an exception?"

A Reusable Validation Helper

In real code, you usually want a small helper rather than scattering try and except blocks everywhere.

python
1import json
2
3def is_valid_json(text: str) -> bool:
4    try:
5        json.loads(text)
6        return True
7    except json.JSONDecodeError:
8        return False
9
10
11print(is_valid_json('{"ok": true}'))
12print(is_valid_json("{bad json}"))

This prints:

text
True
False

This pattern is straightforward and fast enough for most application code. It also keeps the validation rule aligned with the parser you will probably use later anyway.

Returning the Parsed Value Too

Often, a pure boolean is not enough. You validate the string and then immediately need the parsed result. In that case, returning both status and data avoids parsing the same string twice.

python
1import json
2from typing import Any
3
4def parse_json(text: str) -> tuple[bool, Any]:
5    try:
6        return True, json.loads(text)
7    except json.JSONDecodeError:
8        return False, None
9
10
11ok, value = parse_json('["red", "green", "blue"]')
12
13if ok:
14    print("Parsed value:", value)
15else:
16    print("Invalid JSON")

This style is useful in CLI tools, web request handlers, and data import jobs where you want a clean control flow.

Valid JSON Does Not Always Mean "Object"

Many developers expect valid JSON to always be an object with key and value pairs. That is incorrect. A JSON string can also be an array, a number, a string literal, true, false, or null.

python
1import json
2
3examples = [
4    '"hello"',
5    '42',
6    'true',
7    'null',
8    '[1, 2, 3]',
9]
10
11for item in examples:
12    parsed = json.loads(item)
13    print(repr(item), "->", parsed, type(parsed).__name__)

If your application specifically requires a JSON object, validate the syntax first and then validate the resulting type.

python
1import json
2
3def is_json_object(text: str) -> bool:
4    try:
5        return isinstance(json.loads(text), dict)
6    except json.JSONDecodeError:
7        return False

That distinction matters when writing API clients or config loaders. "Valid JSON" and "JSON of the shape I expect" are separate checks.

Capturing Useful Error Details

When the input is invalid, JSONDecodeError includes location information. That is valuable for debugging logs, user feedback, and test failures.

python
1import json
2
3bad_payload = '{"name": "Ada", "age": 37,,}'
4
5try:
6    json.loads(bad_payload)
7except json.JSONDecodeError as exc:
8    print("Message:", exc.msg)
9    print("Line:", exc.lineno)
10    print("Column:", exc.colno)

This makes it much easier to explain what went wrong than just returning False.

Common Pitfalls

One common mistake is using string heuristics such as "starts with [ or "". Those checks only guess the structure; they do not confirm valid syntax.

Another mistake is catching ValueError broadly. While JSONDecodeError inherits from ValueError, catching the more specific exception makes intent clearer and avoids hiding unrelated errors in nearby code.

A third issue is confusing Python literals with JSON literals. JSON uses lowercase true, false, and null. A string containing True or None is not valid JSON even though those are valid Python values.

Finally, be careful with already-parsed data. json.loads expects a string, bytes, or bytearray. If you already have a Python dict, validating it with loads is the wrong operation.

Summary

  • Use json.loads to validate JSON because parsing is the real definition of validity.
  • Catch json.JSONDecodeError to handle invalid input cleanly.
  • Return parsed data along with status when you want to avoid decoding twice.
  • Remember that valid JSON can be a scalar, array, or object.
  • Separate syntax validation from schema or type validation when your application expects a specific shape.

Course illustration
Course illustration

All Rights Reserved.