A support screen occasionally displays the wrong customer. The search field contains one name, but the details below belong to someone searched for moments earlier. Refreshing the page usually clears the problem. The first suggestion is that the cache must be stale.
That explanation is plausible. So are several others: the server returned the wrong record, the browser reused an old result, or a delayed request overwrote a newer one. Editing the cache settings immediately would turn a guess into an intervention before the team had established what happened.
Every error has a history, but the history is rarely visible in one message or stack trace. Debugging is the work of reconstructing enough of it to explain the unexpected result and choose a repair with a clear reason to succeed.
Start With a Precise Disagreement
Write down the expected behaviour and the observation separately. For the support screen, the expectation is that the displayed details correspond to the latest selected customer. The observation is that details from an earlier search sometimes appear after a later search has completed.
That wording is more useful than saying that search is broken. It identifies the relationship that failed and gives the investigation a boundary. It also avoids claiming that the server or cache caused the problem before either has been examined.
Record the sequence, relevant environment, application version, and frequency as far as they are known. If the issue affects a live service, restoring acceptable operation may take priority. A mitigation can reduce the impact while the underlying explanation remains open; record it as such so recovery is not mistaken for proof of a cause.
Build Competing Explanations
Google's SRE chapter on effective troubleshooting describes an iterative process of observing behaviour, forming hypotheses, and testing them. Knowledge of the system helps generate explanations, while experiments determine which explanations remain credible.
For this screen, three hypotheses suggest different evidence:
| Hypothesis | Evidence that would support it |
|---|---|
| The server retrieves the wrong customer. | A response contains a different customer from the one requested. |
| A cache serves an inappropriate result. | The incorrect value can be traced to reuse under an unsuitable cache key or policy. |
| Responses arrive out of order and overwrite current state. | Each response is correct, but an older request updates the screen after the newer one. |
The table is a working model. New evidence may require adding another explanation. Its value is that each hypothesis predicts something observable, allowing the next step to narrow the uncertainty.
Follow the Value Across a Boundary
Inspect the request and response for a failing sequence. If the browser asks for customer B and receives B, but later displays A, the investigation can focus on what happens after those responses reach the client. If the response already contains A, the next useful boundary is further upstream.
A short timeline can make the sequence easier to reason about:
Search A starts
Search B starts
Response B arrives and updates the screen
Response A arrives and updates the screen
If that sequence is observed, it supports the out-of-order hypothesis. It still needs a connection to the state update in the code. A trace showing arrival order does not, by itself, establish which handler changed the displayed customer.
Keep diagnostic records focused on the question. Request identifiers, sequence numbers, and timings may be enough. Copying full customer records into logs adds sensitive data without necessarily helping explain which request was allowed to update the screen.
Choose an Experiment That Separates the Possibilities
For this case, deliberately delay response A until after response B. A mock server or controlled test fixture can reproduce that order without depending on an intermittent network condition.
Before running the experiment, state the prediction: if the client accepts results from superseded searches, the display should change from B back to A. If the display remains B, investigate whether the reproduction preserved the relevant conditions or whether the hypothesis is incomplete.
Changing several things at once makes the outcome harder to interpret. Clearing the cache, restarting the server, adding cancellation, and increasing a timeout might make the symptom disappear while leaving the explanation unresolved. Prefer an experiment whose result tells you which assumption to keep or discard.
Reduce the Case Without Removing the Cause
A smaller reproduction makes the problem easier to inspect and share. Remove unrelated layout, data fields, and service calls while retaining the sequence that produces the failure. In this example, two requests and one shared display state may be enough.
Reduction needs care. Awaiting the first request before starting the second would eliminate the overlap responsible for the suspected bug. The simplified program would pass because it no longer represented the failing situation.
A failed reproduction is still information. Compare its conditions with the original case: timing, cancellation behaviour, navigation, component lifetime, and configuration. Keep track of which differences have been examined. Repeatedly running the same successful scenario rarely explains why another scenario fails.
Repair the Rule That Was Missing
Once the state updates confirm the mechanism, the client needs a rule for which result may be displayed. For example, associate each search with a generation identifier and allow a response to update the screen only if it still belongs to the current search.
Cancellation can reduce unnecessary work, but its guarantees depend on the client and transport involved. The application should still establish whether a result is relevant when it is applied. Error and loading updates need the same consideration: an obsolete request should not clear the current spinner or replace a newer success with an old error.
Keep the repair focused enough that reviewers can connect it to the evidence. If the investigation exposes a wider structural problem, record that separately as a possible technical debt improvement. Expanding the urgent fix into an unrelated redesign makes its effects harder to assess.
Leave Evidence That Outlasts the Investigation
A useful regression check deliberately completes the second request before the first and confirms that the latest selection remains visible. It exercises the failure mechanism rather than relying on ordinary requests happening to arrive in an inconvenient order.
The investigation record should explain the symptom, the relevant sequence, the missing rule, and why the repair addresses it. Include important limits, such as other screens that use a different client and were not examined. A future reader should be able to distinguish established findings from remaining questions.
The customer-facing consequence deserves attention too. Displaying the wrong record may have influenced an action before the person noticed. Following the experience around a bug helps the team decide whether the repair also needs clearer selection feedback or safeguards around consequential actions.
Debugging has produced something durable when the team can explain both why the old behaviour occurred and why the changed behaviour follows from the repair. The error's story becomes useful knowledge: a sequence someone else can understand, challenge, and recognise if related conditions appear again.