Fix the shared test database connection behind the intermittent suite failure #250

doneCreated by Claude Code (User hu_yMavF3p1) • Assigned to Claude Code (User hu_yMavF3p1) • Low priority

Description

Cause

A test-harness defect, not a product defect. WebFactory defaulted to separateConnections: false, which builds the EF options over a single shared SqliteConnection instance used by every AppDb in that host.

The test host starts LiveUpdatePoller and DataExportWorker as background services. When the poller ticks during an HTTP request, both use that one connection at the same time, and DbConnection is not thread-safe. The resulting exception is not one of the translated types, so MCP reported the generic "An error occurred invoking …" instead of a real message.

That explains every earlier observation: the collision hits whichever request happens to be in flight, so it looks unrelated to the failing test and appears at random.

Why the first hypothesis was wrong

"Fails only on the first run after a build" was a coincidence of two samples. Six consecutive cold-start runs were all green. The failure is a timing collision with a timer, so repetition, not a cold machine, is what surfaces it.

Corroboration in the codebase

PrivacyDeletionMcpAndModerationRoutesHideOriginalContent already asked for separateConnections: true on its own. Someone had hit this before and worked around it for a single test instead of correcting the default; the other 24 web-host tests kept sharing one connection.

Fix

7b2c266 makes one connection per context the default, against the same shared-cache in-memory database. No retry and no delay: the cause is removed.

Measured

Before After
ProjectItemTests repeated 1 failure in 30 0 in 40
Full suite repeated 2 failures observed on 2026-09-14 0 in 15

The mechanism is the primary evidence; the counts corroborate it. At a base rate near three percent, these runs make a regression unlikely but do not prove absence.

Acceptance

  • The failing test is named, with its assertion and the condition under which it fails: FreshMcpDiscoveryResolvesBareProjectNumbers, expecting "ReadTool":"task_get" from item_resolve, when a background poller tick overlaps the request.
  • The cause is explained: concurrent use of one shared database connection, not timing inside the test and not shared state between tests.
  • The suite passes repeated runs: 15 full runs and 40 targeted runs after the fix.

Follow-up

#252 records a separate finding from this investigation: item-number allocation reads back after writing and upgrades a shared lock to exclusive, which can deadlock on SQL Server. Unrelated to this failure.

Connection interrupted or session ended. Reload

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.