Skip to content
Braith.

API returns 200, but the data is wrong.

Treat the HTTP response and the application result as two separate checks. A successful request can still return stale data, the wrong account’s data or an unusable result.

Write down the smallest observable contradiction.

Use one request and its expected result. “Save is broken” is difficult to trace. “Saving version 7 returns 200, then an uncached read for this same account returns version 6” gives you a boundary to investigate.

Compare expected and actual JSON with JSON diff. Include record IDs, tenant scope and versions in your private investigation. Never make a public debugging endpoint that exposes another customer’s records.

const expected = { id: "report_1", version: 7, title: "October" };
const actual = { id: "report_1", version: 6, title: "September" };

const resultMatches = expected.id === actual.id
  && expected.version === actual.version
  && expected.title === actual.title;
console.assert(resultMatches === false);

Compare a response that looks successful.

Download the expected report and actual response. Open each in JSON diff. Both are valid JSON and refer to the same record.

The comparison finds two changed paths. Expected JSON has /version 7 and /title October; Actual JSON has /version 6 and /title September. An HTTP status check would not establish whether those values were correct.

To fix a real case, establish whether the write committed first. If the database already has version 7, investigate the read path and cache. If it still has version 6, investigate the write. Returning a different status without correcting the state does not fix the customer's result.

Check the read and write use the same scope.

Follow the authenticated account, record ID and resource version through both requests. A successful write to a different workspace is a correctness and potentially a security problem. Authorisation must be enforced on the server for the specific resource.

If the record is correct in the database, inspect the response serializer, derived fields and whether a later update overwrote it. Do not fix an ownership mismatch by widening access.

Separate stale display from a failed write.

Reloading the whole page is a diagnostic step, not the final fix. Compare the immediate response, the browser cache and a fresh authorised read. Inspect your application cache keys and invalidation. Include tenant and permission context wherever responses differ by account.

Record whether the next read came from the primary database, a replica or an application cache. Do not assume every read observes the same point in time. Keep private responses out of shared public caches.

Test meaning, not only status.

Add an integration test that writes a known value and reads it through the same authorised route the UI uses. Also test the wrong-account request. A test that checks only response.ok would miss the contradiction in the example above.

Reference: MDN’s Fetch guide for response handling. Our local failure lab contains a passing-status, wrong-version case.

Keep checking after the fix.

Braith reviews sampled customer activity for likely problems, including flows you have not defined. Core outcome checks add context where you need it.

Connect with Pro · £59/monthTry Free

Connect first. Pay only when you explicitly activate a paid plan.