Common JSON Reading Errors in Python - Fixes & Solutions

JSON parsing errors are inevitable when working with external data sources, config files, or APIs. Understanding common errors and their fixes saves hours of debugging.

This guide covers the top 12 JSON reading errors in Python with exact error messages, causes, and production-ready solutions.

1. FileNotFoundError

Python
Error and fix
# ❌ ERROR
with open('config.json', 'r') as f:
    data = json.load(f)
# FileNotFoundError: [Errno 2] No such file or directory

# ✅ FIX

import os
from pathlib import Path

file_path = Path('config.json')
if file_path.exists():
    with open(file_path, 'r') as f:
        data = json.load(f)
else:
    print(f"File not found: {file_path.absolute()}")

2. JSONDecodeError - Invalid JSON Syntax

Python
Most common syntax errors
# ❌ Common causes:
# 1. Trailing comma
{"name": "Alice",}

# 2. Single quotes
{'name': 'Bob'}

# 3. Missing quotes
{name: "Charlie"}

# ✅ Universal fix with line numbers

import json

def safe_json_load(filepath: str) -> dict:
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            return json.load(f)
    except json.JSONDecodeError as e:
        print(f"JSON Error at line {e.lineno}, col {e.colno}: {e.msg}")
        print(f"Near: ...{e.doc[max(0,e.pos-20):e.pos+20]}...")
        return {}

3. Extra Data After Parsed JSON

Python
Extra data error fix
# ❌ ERROR
json_str = '{"name": "Alice"} extra text'
json.loads(json_str)
# JSONDecodeError: Extra data: line 1 column 18

# ✅ FIX - Parse only valid JSON portion

import json

def parse_partial_json(text: str):
    try:
        parsed, end = json.JSONDecoder().raw_decode(text)
        return parsed, text[:end].strip()
    except json.JSONDecodeError:
        return {}, text

4. UnicodeDecodeError

Python
Encoding fix
# ❌ ERROR
with open('data.json', 'r') as f:
    json.load(f)
# UnicodeDecodeError: 'charmap' codec can't decode

# ✅ ALWAYS specify encoding
with open('data.json', 'r', encoding='utf-8-sig') as f:
    data = json.load(f)

# Auto-detect encoding

import chardet

with open('data.json', 'rb') as f:
    raw = f.read()
    encoding = chardet.detect(raw)['encoding']
    data = json.loads(raw.decode(encoding))

5. PermissionError

  • File is open in another program
  • Insufficient read permissions
  • File locked by antivirus
Python
Permission safe reading
import os
import stat

def can_read_file(filepath: str) -> bool:
    if os.path.exists(filepath):
        st = os.stat(filepath)
        return (st.st_mode & stat.S_IRUSR) != 0
    return False

if can_read_file('config.json'):
    with open('config.json', 'r') as f:
        data = json.load(f)

6. JSONL (JSON Lines) Mistake

Python
JSON vs JSONL
# ❌ Wrong - treating JSONL as single JSON
with open('data.jsonl') as f:
    data = json.load(f)  # Fails at line 2!

# ✅ Correct JSONL parsing
jsonl_data = []
with open('data.jsonl', 'r') as f:
    for line in f:
        if line.strip():
            jsonl_data.append(json.loads(line))

7. Trailing Commas & Comments

JSON
Invalid JSON with comments
{
  "name": "Alice",
  "age": 25,  // ❌ Trailing comma + comment
}
Python
Remove comments before parsing
import re

def clean_json(text: str) -> str:
    # Remove C-style comments
    text = re.sub(r'//.*', '', text)
    text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
    # Remove trailing commas
    text = re.sub(r',\s*([}\]])', r'\1', text)
    return text

json_str = clean_json(raw_json)
data = json.loads(json_str)

VS Code Debugging Configuration

JSON
.vscode/launch.json for JSON errors
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug JSON Errors",
      "type": "python",
      "request": "launch",
      "program": "${file}",
      "console": "integratedTerminal",
      "exceptionBreakpointFilters": {
        "raised": {
          "filters": ["pythonException"]
        }
      }
    }
  ]
}

Universal JSON Reader (All Errors)

Python
Bulletproof JSON reader
import json
from pathlib import Path
from typing import Any, Dict

class SafeJSONReader:
    @staticmethod
    def read(file_path: str | Path, *, default: Dict[str, Any] = None) -> Dict[str, Any]:
        if default is None:
            default = {}
        
        path = Path(file_path)
        if not path.exists():
            print(f"⚠️  File not found: {path.absolute()}")
            return default
        
        try:
            with open(path, 'r', encoding='utf-8-sig') as f:
                return json.load(f)
        except json.JSONDecodeError as e:
            print(f"❌ JSON Error: line {e.lineno}:{e.colno} - {e.msg}")
            return default
        except UnicodeDecodeError:
            print("❌ Encoding error - try saving as UTF-8")
            return default
        except Exception as e:
            print(f"❌ Unexpected: {e}")
            return default

# Usage
data = SafeJSONReader.read('config.json')

Validation Tools

  • JSONLint.com - Online validator
  • VS Code JSON extension - Real-time validation
  • Pydantic - Runtime validation
  • jsonschema - Schema validation
  • `python -m json.tool file.json` - CLI validation
BASH
CLI validation
python -m json.tool config.json
# Pretty prints valid JSON, errors on invalid

Quick Fix Checklist

  • ✅ Always use `encoding='utf-8'`
  • ✅ Check file exists with `Path.exists()`
  • ✅ Use try-except for `JSONDecodeError`
  • ✅ Validate JSON syntax first
  • ✅ Handle JSONL vs JSON confusion
  • ✅ Set VS Code breakpoints on json.load()

Copy the SafeJSONReader class above for bulletproof JSON reading in all your projects!