Question

Fix JSONDecodeError When Parsing JSON Files in Python

pythonjsonparsing

Question

I have a JSON file that I want to load and print with Python:

{
  "maps": [
    {
      "id": "blabla",
      "iscategorical": "0"
    },
    {
      "id": "blabla",
      "iscategorical": "0"
    }
  ],
  "masks": [
    "id": "valore"
  ],
  "om_points": "value",
  "parameters": [
    "id": "valore"
  ]
}
import json
from pprint import pprint

with open("data.json") as file:
    data = json.load(file)

pprint(data)

Python raises the following error:

json.decoder.JSONDecodeError: Expecting ',' delimiter: line 13 column 13 (char 213)

Why is this file not valid JSON, and how can I correct it so Python can parse the data and access its values?

Short Answer

Python's json.load() can read a JSON file only when its contents follow JSON syntax exactly. You will learn how to interpret JSONDecodeError, correct invalid array entries, load the repaired file, and access nested dictionaries and lists.

Concept

JSON (JavaScript Object Notation) is a text format for structured data. Python translates JSON into built-in data types:

JSON typePython type
Object: {}dict
Array: []list
String: "text"str
Numberint or float
true / falseTrue / False
nullNone

The important rule in this example is that an array contains values separated by commas. A property such as "id": "valore" is a key-value pair, and key-value pairs can appear only inside a JSON object, which uses curly braces.

This is invalid because "id": "valore" is placed directly inside an array:

["id": "valore"]

If id is meant to be a key, wrap the pair in an object:

[{"id": "valore"}]

A parser cannot guess what the intended structure was. It stops at the colon and reports a JSONDecodeError. Valid JSON matters because JSON files are commonly shared among programs, APIs, configuration tools, and databases; all of them require the same strict syntax.

Mental Model

Think of JSON containers as two kinds of storage:

  • An object ({}) is a labelled cabinet. Every item needs a label and a value: "id": "valore".
  • An array ([]) is an ordered shopping basket. It holds values directly: "apple", 42, or an entire labelled cabinet such as { "id": "valore" }.

Putting "id": "valore" directly in an array is like trying to attach a cabinet label to the basket itself. Put the labelled item in a cabinet first, then place that cabinet in the basket.

Take Quiz

Syntax and Examples

Load JSON from a file with json.load(). Use json.loads() only when the JSON is already in a Python string.

import json
from pprint import pprint

with open("data.json", encoding="utf-8") as file:
    data = json.load(file)

pprint(data)

A corrected version of the file, where masks and parameters are arrays of objects, is:

{
  "maps": [
    {
      "id": "blabla",
      "iscategorical": "0"
    },
    {
      "id": "blabla",
      "iscategorical": "0"
    }
  ],
  "masks": [
    {
      "id": "valore"
    }
  ],
  "om_points": "value",
  "parameters": [
    {
      "id": "valore"
    }
  ]
}

After loading it, access values by using dictionary keys and list indexes:

print(data["om_points"])             # value
print(data["maps"][0]["id"])        # blabla
print(data["masks"][0]["id"])       # valore
print(data["parameters"][0]["id"])  # valore

If masks and parameters were intended to contain plain text rather than objects, this is also valid JSON:

"masks": ["valore"]

The correct choice depends on whether you need an id field later.

Step by Step Execution

Consider this JSON fragment:

"masks": [
  {
    "id": "valore"
  }
]

And this Python code:

masks = data["masks"]
first_mask = masks[0]
mask_id = first_mask["id"]
print(mask_id)

Execution proceeds as follows:

  1. data["masks"] retrieves the value associated with the masks key. Its value is a Python list.
  2. masks[0] retrieves the first item in that list. The item is a Python dictionary: {"id": "valore"}.
  3. first_mask["id"] retrieves the string stored under the id key.
  4. print(mask_id) prints valore.

If the JSON had contained "masks": ["valore"], then data["masks"][0] would already be the string "valore"; attempting data["masks"][0]["id"] would fail because strings do not have dictionary keys.

Real World Use Cases

  • Application configuration: Store feature settings, service URLs, and environment-independent options in JSON files.
  • API responses: A web service may return an array of user objects, such as [{"id": 1, "name": "Ava"}].
  • Data exports: Import JSON produced by another system and loop over records in arrays.
  • Metadata files: Describe maps, layers, reports, or assets using nested objects and lists.
  • Automation scripts: Read a JSON job definition, validate required fields, and process each configured item.
Take Quiz

Real Codebase Usage

In real projects, developers usually combine parsing with validation and defensive error handling.

Use a context manager so the file closes automatically, and catch errors when input might be invalid:

import json
from pathlib import Path

path = Path("data.json")

try:
    with path.open(encoding="utf-8") as file:
        data = json.load(file)
except FileNotFoundError:
    print(f"Configuration file not found: {path}")
except json.JSONDecodeError as error:
    print(f"Invalid JSON at line {error.lineno}, column {error.colno}: {error.msg}")
else:
    for map_item in data.get("maps", []):
        map_id = map_item.get("id")
        if not map_id:
            continue
        print(map_id)

Common project patterns include:

  • Validation at the boundary: Check JSON immediately after loading it, before the rest of the application uses it.
  • Safe defaults: Use data.get("maps", []) when an optional list may be absent.
  • Clear schema decisions: Keep records consistently shaped. For example, if one mask is an object with an id, every mask should follow that structure.
  • Useful error messages: Report the file, line, column, and parser message rather than hiding parsing errors.

Common Mistakes

Placing a key-value pair directly in an array

Broken JSON:

"masks": ["id": "valore"]

A colon is valid for an object property, not for an array item. Fix it by using an object:

"masks": [{"id": "valore"}]

Using single quotes

Broken JSON:

{'id': 'valore'}

JSON requires double quotes around keys and string values:

{"id": "valore"}

Python dictionary syntax allows single quotes, but JSON syntax does not.

Leaving a trailing comma

Broken JSON:

{
  "id": "valore",
}

JSON does not allow a comma after the final item. Remove it:

{
  "id": "valore"
}

Confusing json.load() and json.loads()

json.load(file)       # file is an open file object
json.loads(text)      # text is a string containing JSON

Treating JSON strings as Python dictionaries

After loading "masks": ["valore"], the first element is a string, not a dictionary. Use [0], not [0]["id"].

Ignoring the error location

line 13 column 13 identifies where the parser first found syntax it could not accept. The actual mistake can be on that line or immediately before it, such as a missing comma or closing bracket.

Comparisons

StructureJSON syntaxPython resultBest used for
Object{"id": "valore"}dictNamed fields and records
Array["a", "b"]listOrdered collections of values
Array of objects[{"id": "a"}, {"id": "b"}]list[dict]Multiple records with the same fields
String"valore"strA single piece of text

json.load() and json.loads() have similar names but accept different input:

FunctionInputExample
json.load()Open file objectjson.load(file)
json.loads()JSON text in a stringjson.loads('{"id": "a"}')

Use an object when the data has named attributes. Use an array when you need multiple ordered values. An array can contain objects, which is the standard representation for a collection of records.

Take Quiz

Cheat Sheet

import json

# Read JSON from a file
with open("data.json", encoding="utf-8") as file:
    data = json.load(file)

# Parse JSON from a Python string
item = json.loads('{"id": "valore"}')

# Access nested data
value = data["maps"][0]["id"]

# Read an optional key with a fallback
maps = data.get("maps", [])
  • JSON objects use {} and contain "key": value pairs.
  • JSON arrays use [] and contain comma-separated values.
  • A key-value pair inside an array must be wrapped in {}.
  • JSON requires double quotes for keys and strings.
  • Do not use trailing commas.
  • JSONDecodeError includes a line and column to help locate invalid syntax.
  • JSON booleans are true and false; JSON null is null.

FAQ

Why does Python say “Expecting ',' delimiter” for valid-looking JSON?

The message means the parser expected the current array or object item to end or be followed by a comma. In this case, it encountered a colon in an array because "id": "valore" was not wrapped in an object.

Can an array contain an object in JSON?

Yes. This is common:

[{"id": "one"}, {"id": "two"}]

Is {"id": "valore"} valid JSON?

Yes. It is a JSON object with one key, id, and one string value, valore.

Why are single quotes invalid in JSON but valid in Python dictionaries?

JSON is a language-independent format with strict rules requiring double quotes. Python has its own literal syntax, which permits either single or double quotes for strings.

How do I find the line that caused a JSONDecodeError?

Read error.lineno and error.colno, or inspect the line and nearby preceding syntax. A missing comma or bracket just before the reported location can cause the error.

Should iscategorical be a string or a number?

"0" is a string. If the value represents a numeric flag, use 0; if it represents a true/false condition, prefer false or true. Match the format expected by the program consuming the data.

How can I print parsed JSON clearly in Python?

Use pprint(data) for a Python representation, or use json.dumps(data, indent=2) to print it as nicely indented JSON.

Take Quiz

Mini Project

Description

Build a small JSON configuration reader for map metadata. The script loads a JSON file, reports syntax errors clearly, and prints the IDs of configured maps, masks, and parameters. This mirrors the way command-line tools and applications read configuration files.

Goal

Load valid JSON safely and extract IDs from arrays of JSON objects.

Requirements

Create a data.json file with maps, masks, and parameters arrays. Use objects containing an id key for every item in those arrays. Load the file with json.load() and UTF-8 encoding. Print each available ID under a readable label. Display a useful message if the JSON syntax is invalid.

Take Quiz

Keep learning

Related questions

View more