intermediate · investigation

The Enum That Crashed Old Phones

Crash reports spike for mobile app versions older than 6 weeks, all in the account screen. The backend shipped no “breaking” changes — only a new account state for a trust-and-safety feature.

Evidence

crash (app v3.18, Swift):
  Fatal error: Cannot initialize AccountStatus from invalid String value "suspended"

GET /account -> {"status": "suspended", ...}     <- new value, shipped Tuesday

api changelog: "added account status 'suspended' (non-breaking, additive)"
client enum: AccountStatus { active, dormant, closed }   // decode fails hard on unknown
old app versions still active: 31% of MAU

Investigate

Inspect Server change
The server added a new value to an existing enum field — labeled additive in the changelog and shipped without a compatibility review.
Inspect Client decoding behavior
The mobile app decodes `status` into a closed enum that throws on unknown values, and the decode failure crashes the whole screen. No fallback case exists.
Inspect The contract's enum policy
The API docs list the enum values but never state whether the set can grow or what clients must do with unknown values — extensibility was never part of the contract.
Inspect Rollout safeguards
No canary by client version and no contract tests pinned to released app versions; the first signal was crash telemetry, 4 hours in.