Skip to content

fix(proxy): default DB path to home dir and auto-create parents#232

Closed
maciej-konczal wants to merge 1 commit into
HamedMP:mainfrom
maciej-konczal:fix/proxy-db-path-host-default
Closed

fix(proxy): default DB path to home dir and auto-create parents#232
maciej-konczal wants to merge 1 commit into
HamedMP:mainfrom
maciej-konczal:fix/proxy-db-path-host-default

Conversation

@maciej-konczal
Copy link
Copy Markdown

Running bun run dev I got: " TypeError: Cannot open database because the directory does not exist
at getDb (packages/proxy/src/db.ts:9:10)"

@vercel
Copy link
Copy Markdown

vercel Bot commented May 28, 2026

@maciej-konczal is attempting to deploy a commit to the Finna Team on Vercel.

A member of the Team first needs to authorize it.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 28, 2026

Greptile Summary

This PR fixes the TypeError: Cannot open database because the directory does not exist crash seen during local development by changing the default SQLite path from /data/proxy.db to ~/matrixos/proxy.db and auto-creating parent directories with mkdirSync({ recursive: true }) on first connection. A --env-file-if-exists flag is also added to the dev script so the root .env is loaded automatically.

  • packages/proxy/src/db.ts: Default DB path now resolves under homedir(), and a one-time mkdirSync (guarded by the existing singleton check) ensures the parent directory exists before better-sqlite3 opens the file.
  • packages/proxy/package.json: tsx watch dev script gains --env-file-if-exists=../../.env, which silently skips the file if absent — compatible with tsx ^4.21.0.
  • tests/proxy/db.test.ts: New test covers the auto-create behaviour using vi.resetModules() and a dynamic import to pick up the per-test PROXY_DB_PATH value.

Confidence Score: 4/5

Safe to merge — the core fix is a minimal, well-scoped change to db.ts, and the new dev-script flag is backwards-compatible.

The implementation is correct and the test covers the primary behaviour. The only gap is that the test never closes the database handle before resetting modules and deleting the temp directory; adding more test cases without addressing this will accumulate open file descriptors and could break cleanup on non-Linux platforms.

tests/proxy/db.test.ts — database handle should be closed before vi.resetModules() and tmpDir cleanup to keep the pattern safe as the test suite grows.

Important Files Changed

Filename Overview
packages/proxy/src/db.ts Adds mkdirSync with recursive:true inside the singleton guard and changes the default path to ~/matrixos/proxy.db; change is correct and safe — mkdir only runs once on first DB init.
packages/proxy/package.json Adds --env-file-if-exists=../../.env to the dev script; tsx ^4.21.0 supports this flag and it silently skips if .env is absent — clean DX improvement.
tests/proxy/db.test.ts New test correctly verifies parent-dir creation via vi.resetModules + dynamic import pattern, but does not close the database handle before module reset and tmpDir cleanup.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[getDb called] --> B{db singleton\ninitialized?}
    B -- yes --> G[return db]
    B -- no --> C[resolve DB_PATH\nPROXY_DB_PATH env\nor ~/matrixos/proxy.db]
    C --> D[mkdirSync dirname DB_PATH\nrecursive: true]
    D --> E[new Database DB_PATH]
    E --> F[pragma WAL + foreign_keys\nmigrate schema]
    F --> G
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
tests/proxy/db.test.ts:24-29
**Open database handle not closed before cleanup**

`getDb()` initialises a module-level singleton that keeps `better-sqlite3`'s database file open. The test never calls `db.close()` (or equivalent) before `vi.resetModules()` and `fs.rmSync()` run in `afterEach`. On Linux the unlink succeeds because the OS allows deleting open files, but the old module's `Database` instance keeps holding the file descriptor until it is garbage-collected. As more `it` blocks are added (e.g. for `insertUsage`, `checkQuota`), each reset accumulates a stale, unclosed handle — which can trigger warnings from `better-sqlite3` and would break the cleanup entirely on Windows. The module should export a `closeDb()` helper (or the test should grab the return value of `getDb()` and call `.close()` directly) before the module is reset.

Reviews (1): Last reviewed commit: "fix(proxy): default DB path to home dir ..." | Re-trigger Greptile

Comment thread tests/proxy/db.test.ts
Comment on lines +24 to +29

it("creates the parent directory if it does not exist", async () => {
const { getDb } = await import("../../packages/proxy/src/db.js");
expect(() => getDb()).not.toThrow();
expect(fs.existsSync(dbPath)).toBe(true);
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Open database handle not closed before cleanup

getDb() initialises a module-level singleton that keeps better-sqlite3's database file open. The test never calls db.close() (or equivalent) before vi.resetModules() and fs.rmSync() run in afterEach. On Linux the unlink succeeds because the OS allows deleting open files, but the old module's Database instance keeps holding the file descriptor until it is garbage-collected. As more it blocks are added (e.g. for insertUsage, checkQuota), each reset accumulates a stale, unclosed handle — which can trigger warnings from better-sqlite3 and would break the cleanup entirely on Windows. The module should export a closeDb() helper (or the test should grab the return value of getDb() and call .close() directly) before the module is reset.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/proxy/db.test.ts
Line: 24-29

Comment:
**Open database handle not closed before cleanup**

`getDb()` initialises a module-level singleton that keeps `better-sqlite3`'s database file open. The test never calls `db.close()` (or equivalent) before `vi.resetModules()` and `fs.rmSync()` run in `afterEach`. On Linux the unlink succeeds because the OS allows deleting open files, but the old module's `Database` instance keeps holding the file descriptor until it is garbage-collected. As more `it` blocks are added (e.g. for `insertUsage`, `checkQuota`), each reset accumulates a stale, unclosed handle — which can trigger warnings from `better-sqlite3` and would break the cleanup entirely on Windows. The module should export a `closeDb()` helper (or the test should grab the return value of `getDb()` and call `.close()` directly) before the module is reset.

How can I resolve this? If you propose a fix, please make it concise.

@HamedMP
Copy link
Copy Markdown
Owner

HamedMP commented May 28, 2026

thanks for the pr @maciej-konczal . we have moved away from sqlite, to postgres only. sqlite has been the old db and soem coding agents (mainly claude) still makes mistake. we should move completely to codex.

The proper fix is to migrate the proxy persistence tables (api_usage, user_quotas) to Postgres/Kysely using DATABASE_URL or the existing platform/owner Postgres wiring, then remove better-sqlite3 from @matrix-os/proxy.

@maciej-konczal
Copy link
Copy Markdown
Author

Closing and #235 provided

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants