You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
server/src/routes/voices.test.ts has intra-file state pollution: the plan-108 series-scope test fails on main when run with the rest of its own file, and retry: 1 has been hiding it.
The failing test
FAIL src/routes/voices.test.ts
> PUT /api/voices/:voiceId/override — series scope (plan 108)
> writes ONLY to the anchor book's series, leaving other series untouched
AssertionError: expected { …(2) } to be undefined
- Expected: undefined
+ Received: { "coqui": { "name": "Daisy Studious" },
"qwen": { "name": "qwen-catalogue-pick" } }
expect(other.characters[0].overrideTtsVoices).toBeUndefined();
An earlier test in the same file leaves overrideTtsVoices on the cross-series book's cast.json, and this test then reads it.
Reproduction
On main @ 365d7c60, from server/:
npx vitest run src/routes/voices.test.ts --retry=0 # 1 failed | 60 passed
npx vitest run src/routes/voices.test.ts # 61 passed <- retry masks it
npx vitest run src/routes/voices.test.ts --retry=0 -t "writes ONLY to the anchor book"
# 1 passed | 60 skipped
Triage
Not a product bug. The test passes when run alone, so the route behaves correctly — the leaked state comes from a sibling test, not from voices.ts.
Masked by retry: 1 (server/vitest.config.ts). The retry re-runs after the failing test's afterEach has cleaned up, so the second attempt passes and the run reports green. This is exactly the hazard ops-46 — vitest retry:1 can turn a genuine red-phase test green #2028 describes — see the note added there.
Not indocs/testing/flaky-register.md, and this is not flakiness: with --retry=0 it fails deterministically.
Suspect commit:b913d842 ("refactor(frontend,server): centralise the narrator/char-narrator id pair") is the most recent change touching both voices.ts and voices.test.ts. Not confirmed by bisect.
Acceptance
Identify which earlier test in voices.test.ts leaks overrideTtsVoices onto the cross-series book, and stop it leaking (fix the test, or reset the fixture between tests — whichever is the smaller, more honest change).
npx vitest run src/routes/voices.test.ts --retry=0 is green.
The fix is mutation-verified: reintroducing the leak must redden the plan-108 test with --retry=0.
server/src/routes/voices.test.tshas intra-file state pollution: the plan-108 series-scope test fails onmainwhen run with the rest of its own file, andretry: 1has been hiding it.The failing test
An earlier test in the same file leaves
overrideTtsVoiceson the cross-series book's cast.json, and this test then reads it.Reproduction
On
main@365d7c60, fromserver/:Triage
voices.ts.feat/server-1981-cast-lock, srv — #1953's designed-arm manifest read yields inside the cast.json read-modify-write window #1981), which does not touchvoices.tsorvoices.test.ts—git diff 44378d3e..HEAD --statis empty for both. Confirmed independently on a cleanmaincheckout.retry: 1(server/vitest.config.ts). The retry re-runs after the failing test'safterEachhas cleaned up, so the second attempt passes and the run reports green. This is exactly the hazard ops-46 — vitest retry:1 can turn a genuine red-phase test green #2028 describes — see the note added there.docs/testing/flaky-register.md, and this is not flakiness: with--retry=0it fails deterministically.b913d842("refactor(frontend,server): centralise the narrator/char-narrator id pair") is the most recent change touching bothvoices.tsandvoices.test.ts. Not confirmed by bisect.Acceptance
voices.test.tsleaksoverrideTtsVoicesonto the cross-series book, and stop it leaking (fix the test, or reset the fixture between tests — whichever is the smaller, more honest change).npx vitest run src/routes/voices.test.ts --retry=0is green.--retry=0.Key files
server/src/routes/voices.test.tsserver/vitest.config.ts(theretry: 1that masked this — see ops-46 — vitest retry:1 can turn a genuine red-phase test green #2028)