Skip to content
Prathamesh Kasar
Work

Production case study

Proving a race condition with Playwright

Two APIs, page submit and last-visited page, were racing each other. I proved it with a Playwright concurrency script, then fixed it.

Role
Developer, bbSlate
When
2025–2026
Where
bbSlate core APIs
Stack
  • ASP.NET Core
  • Playwright
  • SQL Server

2 APIsracing, reproduced on demand

Context

In bbSlate, students work through pages. Two APIs run close together: one submits the page, and one records the last page the student visited, so they can pick up where they left off.

Problem

Sometimes the saved state was wrong, and it was not repeatable by hand. Clicking through the flow worked almost every time. A bug that only shows up under timing is easy to wave away as "can't reproduce".

Investigation

Both calls touch the same student's state, close together in time. If they arrive in an unlucky order, or overlap, one can overwrite the other. That was a theory; it needed proof.

I wrote a Playwright script that fires the two API calls concurrently, many times, and checks the stored state after each round. A person clicking can't control timing. A script can.

Root cause

The script reproduced the wrong state reliably. The two APIs were racing on the same data, and the result depended on which one finished last.

Fix

With the race reproducible on demand, I fixed it and used the same script as the check: it failed before the fix and passed after. In the same area I also fixed grader submission failures, an HTTP 200 returned for expired tokens, and missing token-expiry logs.

Result

An intermittent "can't reproduce" became a proven, fixed bug with a test that keeps it fixed.

What I learned

Turn "it happens sometimes" into a test that fails every time. When a bug depends on timing, make the timing the input of the test.