Findings
The test suite emptied the live SQLite database
Date: 2026-09-16
Area: packages/server/vitest.config.ts, packages/server/tests/setup.ts, docker-compose.yml
What happened#
A full vitest run of the server package rewrote data/tokens.db at the repo
root: the users table afterwards held one row, bob, a fixture from
users.test.ts. That file is what docker-compose.yml bind-mounts as the
container's /data/tokens.db, so the running server lost its only real user —
the SSO account, its API key, and with them the routing to that user's
workspace directory and browser profile (both keyed by user id).
Why#
Three things lined up, none of them wrong on its own:
config.DATABASE_URLdefaults to./data/tokens.db, relative to the process cwd.- The test suite runs against a real SQLite file at that default, and the DB
suites begin with
DELETE FROM users.fileParallelism: falseexists to keep those deletes from racing each other; nothing kept them off a database that mattered. - The repo's
data/directory is both the developer's local database and the compose bind mount for the live one.
Every previous run had a cwd of packages/server and wrote to
packages/server/data/tokens.db, a file nobody reads. One run resolved
./data against the repo root instead and hit the live file. Nothing in the
suite could tell the difference.
Fix#
vitest.config.ts now sets DATABASE_URL and WORKSPACE_DIR for the whole
suite to a per-process directory under the OS temp dir. A test
(tests/db-isolation.test.ts) asserts the resolved database path is absolute
and not under the repository, so a future config change that drops the
override fails immediately rather than on the next unlucky cwd.
Recovery#
The user row was re-inserted with its original id and email. Google SSO looks
a login up by google_sub, then by email, and links the sub on match, so
the next sign-in reattaches to the row — and to the workspace and profile
directories named by that id. The API key was not recoverable (only a hash and
an encrypted copy were stored, both in the lost row); it has to be minted
again in the portal.
Lesson#
A test suite that opens a real database at a relative default path is one
cwd away from production data. Pin the test database to a path the suite
owns, and assert it.