flashman
← All posts

JSON enum casing: debug API contract mismatches

Debug JSON enum casing bugs by formatting payloads, diffing examples, checking generated clients, and documenting exact API values before risky rollout.

2026-07-20 · 5 min read · Rahul Chitturi

  • json
  • api
  • debugging

Enum values look simple until one client sends ACTIVE, another sends active, and a generated SDK expects Active. The JSON is valid in every case, but the API contract is no longer obvious to humans or machines.

These bugs often appear during migrations from database constants to public API values, mobile client releases, or TypeScript-to-backend code generation. A casing mismatch can turn into rejected requests, silently ignored filters, or analytics buckets that split the same state into multiple names.

Compare examples before changing code

Start with a known-good request, a failing request, and the schema or docs that describe the enum. Format the payloads and diff them so the only visible difference is the value shape.

  • Check whether the contract allows uppercase, lowercase, camelCase, or snake_case
  • Confirm generated clients do not transform enum values during serialization
  • Look for UI labels being reused as wire values
  • Verify database migrations did not leak internal constants into the public API

Document the wire value

A reliable fix names the exact wire value and keeps presentation labels separate. If the API needs to accept old and new values during a rollout, document the compatibility window and add tests for both shapes.

For incident notes, keep sanitized payloads with realistic enum names. The important detail is not customer data; it is where the casing changed and which component treated the value as trusted.

A Flashman workflow

Use the JSON formatter to inspect request bodies, the case converter to check naming variants, and the diff tool to compare examples from docs, SDKs, logs, and tests.

End with a small contract checklist: accepted values, rejected values, serializer behavior, migration behavior, and the UI label that should not cross the API boundary.

Try these tools