Skip to content

REQ-F-074: JSON Null/Absent/Empty Convention

Tier: Framework-Automatic | Priority: P1

Source: Silent assumption — agents branch on field presence/value; tools that use null, absent, and empty string interchangeably cause agents to take wrong code paths silently

Addresses: Severity: High / Token Spend: Medium / Time: Low / Context: Medium


Description

The framework MUST enforce a consistent three-way distinction in all JSON output:

  • Absent field (key not present): the feature or field is not supported by this command or this version of the tool
  • null: the feature is supported; the value is explicitly unset or unknown
  • "" (empty string) or [] (empty array): the feature is supported; the value is explicitly empty

The framework MUST never substitute one for another. A field that was present in a previous response MUST remain present (possibly as null) in subsequent responses for the same command — disappearing fields break agent parsers that check for key presence.

Acceptance Criteria

  • A field documented as optional in the schema is either always present (as null when unset) or always absent — never alternates between the two
  • "" is never used where null is semantically correct (unset vs empty are different states)
  • [] is returned for empty collections, never null or absent
  • Schema documentation explicitly marks each field as: required (never null/absent), nullable (present but may be null), or optional (may be absent if feature unsupported)
  • Two calls to the same command under the same conditions produce the same set of keys

Schema

response-envelope — the data field and all nested objects must follow this convention


Wire Format

Correct:

{
  "name": "my-resource",
  "description": null,      ← supported, currently unset
  "tags": [],               ← supported, currently empty
  "deprecated_at": null     ← supported, not deprecated yet
}

Incorrect:

{
  "name": "my-resource",
  "description": "",        ← wrong: empty string ≠ unset
                            ← tags absent: wrong, should be []
  "deprecated_at": ""       ← wrong: empty string ≠ null
}

Example

Agent checking if a resource is deprecated:

if "deprecated_at" not in response["data"]:
    # Tool version doesn't support deprecation tracking — skip
elif response["data"]["deprecated_at"] is None:
    # Feature supported, resource not deprecated
else:
    # Resource deprecated at response["data"]["deprecated_at"]

This three-way check only works correctly when the convention is consistently applied.


Requirement Tier Relationship
REQ-F-004 F Provides: envelope structure within which this convention applies
REQ-F-022 F Composes: schema version lets agents know which fields to expect in which version
REQ-C-015 C Provides: per-command schema that must document each field's nullability