High severity intermediate · Fix: 5-10 min

json.JSONDecodeError

json.decoder.JSONDecodeError

What this error means
This error occurs when chat history data cannot be serialized or deserialized as valid JSON due to invalid characters or structure.

Stack trace

traceback
Traceback (most recent call last):
  File "app.py", line 42, in save_chat_history
    json_data = json.dumps(chat_history)  # <-- error here
  File "/usr/lib/python3.9/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python3.9/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.9/json/encoder.py", line 257, in iterencode
    raise JSONDecodeError("Invalid control character at", s, err.value) from None
json.decoder.JSONDecodeError: Invalid control character at: line 1 column 15 (char 14)
QUICK FIX
Wrap json.dumps and json.loads calls in try/except JSONDecodeError and sanitize chat history strings before serialization.

Why it happens

Chat history often contains user input or model output with special characters or non-serializable objects. When attempting to serialize or deserialize this data as JSON, invalid control characters or unsupported types cause the JSONDecodeError. This typically happens if the chat history includes raw binary data, unescaped control characters, or circular references.

Detection

Monitor serialization calls with try/except blocks catching JSONDecodeError and log the raw chat history content causing failure to identify problematic entries before crashing.

Causes & fixes

1

Chat history contains unescaped control characters like newlines or tabs in strings

✓ Fix

Sanitize or escape control characters in chat messages before serialization using json.dumps with ensure_ascii=True or manual string cleaning

2

Chat history includes non-serializable Python objects such as datetime, bytes, or custom classes

✓ Fix

Convert non-serializable objects to JSON-compatible types (e.g., ISO strings for datetime) before serialization

3

Corrupted or partial chat history data causing malformed JSON structure

✓ Fix

Validate chat history data integrity before serialization and implement fallback recovery or data cleansing routines

4

Using incompatible JSON libraries or versions that handle encoding differently

✓ Fix

Use Python's built-in json module consistently and ensure environment uses supported Python version (3.7+)

Code: broken vs fixed

Broken - triggers the error
python
import json

def save_chat_history(chat_history):
    # This line raises JSONDecodeError if chat_history has invalid chars
    json_data = json.dumps(chat_history)  # <-- error here
    with open('history.json', 'w') as f:
        f.write(json_data)

chat_history = {'messages': ['Hello\x0cWorld', 'Test']}
save_chat_history(chat_history)
Fixed - works correctly
python
import json
import os

def sanitize_for_json(obj):
    if isinstance(obj, str):
        return obj.encode('unicode_escape').decode('utf-8')
    if isinstance(obj, dict):
        return {k: sanitize_for_json(v) for k, v in obj.items()}
    if isinstance(obj, list):
        return [sanitize_for_json(i) for i in obj]
    return obj

def save_chat_history(chat_history):
    sanitized = sanitize_for_json(chat_history)  # sanitize control chars
    json_data = json.dumps(sanitized, ensure_ascii=True)  # fixed: ensure_ascii escapes control chars
    with open('history.json', 'w') as f:
        f.write(json_data)

chat_history = {'messages': ['Hello\x0cWorld', 'Test']}
save_chat_history(chat_history)  # works without JSONDecodeError
Added a sanitize_for_json function to escape control characters and used ensure_ascii=True in json.dumps to prevent JSONDecodeError from invalid characters.

Workaround

Catch JSONDecodeError during serialization, then manually clean or remove problematic entries from chat history strings before retrying serialization.

Prevention

Design chat history storage to only include JSON-serializable types and sanitize all user/model text inputs on ingestion to avoid invalid characters or unsupported types.

Python 3.7+ · json (builtin) >=3.7 · tested on 3.9
Verified 2026-04
Verify ↗

Community Notes

No notes yetBe the first to share a version-specific fix or tip.