Select Page

Python JSONDecodeError: Expecting value: line 1 column 1 (char 0)

by | Programming, Python, Tips

If you try to parse invalid JSON or decode an empty string as JSON, you will encounter the JSONDecodeError: Expecting value: line 1 column 1 (char 0). This error can occur if you read an empty file using json.load, read an empty JSON or receive an empty response from an API call.

You can use a try-except code block to catch the error and then check the contents of the JSON string or file before retrying.

This tutorial will go through the error in detail and how to solve it with code examples.


JSONDecodeError: Expecting value: line 1 column 1 (char 0)

In Python, JSONDecodeError occurs when there is an issue with the formatting of the JSON data. This specific error tells us the JSON decoder has encountered an empty JSON.

Example #1: Incorrect use of json.loads()

Let’s look at an example where we have a JSON file with the following contents:

[
        {"margherita":7.99},
        {"pepperoni":9.99},
        {"four cheeses":10.99}
]

We want to read the data into a program using the json library. Let’s look at the code:

import json

json_path = 'pizza.json'

data = json.loads(json_path)

In the above code, we try to read the data in using json.loads(). Let’s run the code to see the result:

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

The error occurs because json.loads() expects a JSON encoded string, not a filename. The string pizza.json is not a valid JSON encoded string.

Solution

We need to use json.load() instead of json.loads() to read a file. Let’s look at the revised code:

import json

json_path = 'pizza.json'

with open(json_path, 'r') as f:

    data = json.loads(f.read())

print(data)

In the above code, we use the open() function to create a file object that json.load() can read and return the decoded data object. The with statement is a context manager that ensures that the file is closed once the code is complete. Let’s run the code to see the result:

[{'margherita': 7.99}, {'pepperoni': 9.99}, {'four cheeses': 10.99}]

Example #2: Empty JSON file

Let’s look at an example where we have an empty file, which we will try to read in using json.loads(). The file is called particles.json. Since the JSON file is empty, the JSON decoder will throw the JSONDecodeError when it tries to read the file’s contents. Let’s look at the code:

import json

filename = 'particles.json'

with open(filename, 'r') as f:
    contents = json.loads(f.read())
    print(contents)
---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
Input In [1], in <cell line: 5>()
      3 filename = 'particles.json'
      5 with open(filename, 'r') as f:
----> 6     contents = json.loads(f.read())
      7     print(contents)

File ~/opt/anaconda3/lib/python3.8/json/__init__.py:357, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    352     del kw['encoding']
    354 if (cls is None and object_hook is None and
    355         parse_int is None and parse_float is None and
    356         parse_constant is None and object_pairs_hook is None and not kw):
--> 357     return _default_decoder.decode(s)
    358 if cls is None:
    359     cls = JSONDecoder

File ~/opt/anaconda3/lib/python3.8/json/decoder.py:337, in JSONDecoder.decode(self, s, _w)
    332 def decode(self, s, _w=WHITESPACE.match):
    333     """Return the Python representation of ``s`` (a ``str`` instance
    334     containing a JSON document).
    335 
    336     """
--> 337     obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    338     end = _w(s, end).end()
    339     if end != len(s):

File ~/opt/anaconda3/lib/python3.8/json/decoder.py:355, in JSONDecoder.raw_decode(self, s, idx)
    353     obj, end = self.scan_once(s, idx)
    354 except StopIteration as err:
--> 355     raise JSONDecodeError("Expecting value", s, err.value) from None
    356 return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Solution

If the file is empty, it is good practice to add a try-except statement to catch the JSONDecodeError. Let’s look at the code:

import json

filename = 'particles.json'

with open(filename, 'r') as f:

   try:

       contents = json.loads(f.read())

       print(contents)

   except json.decoder.JSONDecodeError:

       print('File is empty')
File is empty

Now we have verified the file is empty, we can add some content to the file. We will add three particle names together with their masses.

[
        {"proton":938.3},
        {"neutron":939.6},
        {"electron":0.51}
]

Let’s try to read the JSON file into our program and print the contents to the console:

import json

filename = 'particles.json'

with open(filename, 'r') as f:

   try:

       contents = json.loads(f.read())

       print(contents)

   except json.decoder.JSONDecodeError:

       print('File is empty')
[{'proton': 938.3}, {'neutron': 939.6}, {'electron': 0.51}]

We successfully read the contents of the file into a list object.

Example #3: Response Request

Let’s look at an example where we want to parse a JSON response using the requests library. We will send a RESTful GET call to a server, and in return, we get a response in JSON format. The requests library has a built-in JSON decoder, response.json(), which provides the payload data in the JSON serialized format.

We may encounter a response that has an error status code or is not content-type application/json. We must check that the response status code is 200 (OK) before performing the JSON parse. Let’s look at the code to check the response has the 200 status code and has the valid content type. application/json.

import requests

from requests.exceptions import HTTPError

url = 'https://httpbin.org/get'

try:

    response = requests.get(url)

    status = response.status_code

    if (status != 204 and response.headers["content-type"].strip().startswith("application/json")):

        try:

            json_response = response.json()

            print(json_response)

        except ValueError:
            
            print('Bad Data from Server. Response content is not valid JSON')

    elif (status != 204):

        try:

            print(response.text)

        except ValueError:

            print('Bad Data From Server. Reponse content is not valid text')

except HTTPError as http_err:

    print(f'HTTP error occurred: {http_err}')

except Exception as err:

    print(f'Other error occurred: {err}')

In the above example, we use httpbin.org to execute a GET call. Let’s run the code to get the result:

{'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate, br', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.27.1', 'X-Amzn-Trace-Id': 'Root=1-6265a5c1-3b57327c02057a3a39ffe86d'}, 'origin': '90.206.95.191', 'url': 'https://httpbin.org/get'}

Summary

Congratulations on reading to the end of this tutorial! The JSONDecodeError: Expecting value: line 1 column 1 (char 0) occurs either when data is not present in a file, the JSON string is empty, or the payload from a RESTful call is empty.

You can resolve this error by checking the JSON file or string for valid content and using an if-statement when making a RESTful call to ensure the status code is 200 and the content type is application/json.

For further reading on errors involving JSON, go to the articles:

Have fun and happy researching!