Data-Loss Bugs Start at Requirements
Functional Requirements Get Written Down. Data Requirements Don't.
Requirements docs describe what a feature does in detail: screen flows, button behavior, API response shapes. What they usually skip is the data itself. When you add a new field, what's the default value? What happens to existing records that don't have it? How long should it be kept? None of this ends up in the spec, so whoever implements the feature makes a judgment call on the spot — usually "this should be fine."
Ad-hoc judgment calls usually work, which is exactly why nobody notices. The problem surfaces later, when something actually hits the case nobody decided on — almost always old or migrated data.
A Real Failure: The Order Detail Page That Went Blank
An e-commerce team implemented a requirement: "show the estimated delivery date on the order list." New orders got the date calculated and stored correctly, and the display worked fine. QA passed every test case, because every test case used a freshly created order.
After release, reports came in that some old orders' detail pages rendered completely blank. The cause was simple: the estimated-delivery-date field only existed on orders created after the release. Every order placed before that had the field as NULL. The display component assumed the date always had a value and threw an exception when it formatted NULL.
During the requirements review, "how do we display the estimated delivery date" was discussed at length. Nobody asked "how do we display an order that doesn't have one." A single line deciding how to handle pre-existing data would have prevented the whole incident.
A Data Requirements Checklist
Every time you design a new field, table, or collection, fill in these four items at the requirements stage — not later. The point is to disallow "we'll decide during implementation."
1. Default Value
What's the default on creation? Spell out a value that actually means something for the business — empty string, zero, false, current timestamp. "Just use null for now" isn't a decision, it's a decision deferred.
2. Required vs. Optional (Nullability)
Can code safely assume this field always has a value? Check that the frontend, the API, and the database all agree on this assumption. A classic failure mode: the database allows NULL, but the frontend code was written as if the value is always present.
3. Handling of Migrated Data
How does this field get filled in for existing records? There are generally three options:
- Backfill it (populate all existing records in one pass)
- Leave it NULL and write explicit fallback handling wherever it's read
- Explicitly scope it out (old records are simply not covered by this feature)
Any of these is fine. Picking none of them and moving on to implementation is the mistake.
4. Retention Period
How long is this data kept, and why — legal requirement, compliance policy, or just storage cost? Fields containing personal data are exactly the ones where deciding "when do we delete this" later takes the longest to resolve internally.
Bake It Into the Requirements Review
Rather than folding this into the general functional review, keep a small table per changed data field. It's easier to enforce than it sounds.
| Field | Default | Nullable | Migrated Data | Retention |
|--------------------------|-------------|----------|-----------------------|--------------|
| shipping_estimated_at | none | No | Backfilled | Same as order|
| referral_source | "unknown" | Yes | Out of scope (new only)| 2 years |
Don't let a review pass with any cell still marked "TBD." That alone stops these decisions from being pushed into a later phase.
Bugoon in Practice
Even with a checklist in place, some cases slip through. Missing-data bugs tend to surface as "the page breaks only for certain old records" — hard to reproduce, and the person reporting it usually has no idea which record triggered it. All they can say is "this screen goes blank."
With Bugoon's widget, a reporter can attach a screenshot and the steps they took right when it happens, and once it's linked to a GitHub Issue, the engineer gets that context up front instead of starting from scratch. Less time spent narrowing down the trigger means more time to trace it back to the actual root cause — in cases like this, a data requirement that was never decided.
Streamline bug reporting for your team.
Bugoon is free to get started. Add one line of code to your site and transform how your team handles bugs.
Get Started