Skip to content

voices.test.ts leaks overrideTtsVoices across tests; retry:1 hides the failure on main #2081

Description

@dudarenok-maker

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.
  • Pre-existing, not branch-induced. Found while running the cast-lock sweep (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 touch voices.ts or voices.test.tsgit diff 44378d3e..HEAD --stat is empty for both. Confirmed independently on a clean main checkout.
  • 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 in docs/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.

Key files

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugDefect — tracked via issues, off the MoSCoW backlog

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions