Batu Lab NotesPractical developer guides

Avoid treating an empty JSON object as a missing value

By Batu · English technical notes

To avoid treating an empty JSON object as missing, test payload is None, not if not payload. An empty object is a valid JSON value and decodes to the falsy Python dictionary {}.

The example starts with two boundary inputs: Python None, used here as an application-level absent value, and '{}', decoded by json.loads(). The incorrect helper uses truthiness, so it returns "missing" for both None and {}. Its printed output demonstrates the bug without relying on a file or network request.

The corrected helper reserves None for absence. It returns "present-empty" for {} and "present-nonempty" for a dictionary that has values. This is intentionally not a schema validator: it does not decide whether an empty object is permitted by every API. Instead, it preserves the important distinction so a caller can enforce its own object-content rules afterwards. The assertions pin down all three cases.

The json documentation specifies the normal mapping between JSON objects and Python dictionaries; Python’s truth-value rules explain why an empty dictionary is false in a boolean context in the standard type documentation. Both APIs are long established; Python 3.8+ is a practical minimum.

AI assistance disclosure: this article was drafted with AI assistance and uses synthetic in-memory values.

import json


def wrong_status(payload):
    return "missing" if not payload else "present"


def status(payload):
    if payload is None:
        return "missing"
    if payload == {}:
        return "present-empty"
    return "present-nonempty"


missing = None
empty = json.loads("{}")
nonempty = json.loads('{"enabled": true}')

assert wrong_status(missing) == "missing"
assert wrong_status(empty) == "missing"
assert status(missing) == "missing"
assert status(empty) == "present-empty"
assert status(nonempty) == "present-nonempty"

print(wrong_status(missing), wrong_status(empty))
print(status(missing), status(empty), status(nonempty))
missing missing
missing present-empty present-nonempty