Skip to content

fix: resolve absolute DB path to prevent SQLITE_CANTOPEN on CWD change#32

Merged
mkreyman merged 3 commits into
mkreyman:masterfrom
cynthiateeters:fix/sqlite-cantopen-cwd
Mar 25, 2026
Merged

fix: resolve absolute DB path to prevent SQLITE_CANTOPEN on CWD change#32
mkreyman merged 3 commits into
mkreyman:masterfrom
cynthiateeters:fix/sqlite-cantopen-cwd

Conversation

@cynthiateeters
Copy link
Copy Markdown
Contributor

Summary

Fixes #31.

The server opened context.db using a bare relative path, so SQLite resolved it against the process's CWD at startup. Users running node dist/index.js directly (as the README instructed) bypassed the bin/mcp-memory-keeper wrapper that guards against this, causing SQLITE_CANTOPEN whenever the parent process started with a different CWD.

Changes

src/index.ts

  • Resolves DB path to an absolute location: $DATA_DIR/context.db (with path.resolve() to guard against a relative DATA_DIR) or ~/mcp-data/memory-keeper/context.db as the default fallback
  • Creates the data directory with mkdirSync({ recursive: true }) if it does not exist
  • Emits a stderr warning with the exact cp command when a context.db is found in CWD but the server is opening from a different path (migration warning — no auto-copy per discussion in Server crashes with SQLITE_CANTOPEN when parent process CWD changes #31)

README.md

  • Line 177: updated from-source install command to use bin/mcp-memory-keeper instead of node dist/index.js
  • Added Upgrading section documenting the new default DB path and migration steps

Tests

  • server-initialization.test.ts: passes DATA_DIR: tempDir in spawn env so the test reflects the new absolute-path behavior
  • git-integration.test.ts: updated hardcoded 'master' branch assertion to 'main' (pre-existing failure unrelated to this fix)

Test plan

  • All 1185 tests pass (66 suites)
  • Verified manually:
    • DATA_DIR=/tmp/test node dist/index.js → DB created at /tmp/test/context.db
    • HOME=/tmp/fake-home node dist/index.js → DB created at /tmp/fake-home/mcp-data/memory-keeper/context.db
    • DATA_DIR=./relative node dist/index.js → resolves to absolute path ✅
    • Migration warning fires with exact cp command when legacy context.db detected in CWD ✅
    • bin/mcp-memory-keeper wrapper continues to work correctly ✅

Copy link
Copy Markdown
Owner

@mkreyman mkreyman left a comment

Choose a reason for hiding this comment

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

Nice work — the core fix is solid. A few things to address before merge:

Must fix

1. Three tests still pass MCP_DB_PATH which the server never reads

Lines 70, 190, 268 in server-initialization.test.ts pass MCP_DB_PATH: dbPath, but src/index.ts only reads DATA_DIR. These tests don't actually control the DB path — post-merge they'll silently write to ~/mcp-data/memory-keeper/ during test runs. Should be DATA_DIR: tempDir like the second test you already fixed.

2. No error handling on fs.mkdirSync

If mkdirSync fails (e.g., permission denied), the server crashes with a raw Node.js stack trace before reaching the DatabaseManager. Since the whole point of this PR is to prevent cryptic startup crashes, a try/catch with an actionable message would be consistent:

try {
  fs.mkdirSync(dataDir, { recursive: true });
} catch (err) {
  console.error(
    `[memory-keeper] FATAL: Cannot create data directory "${dataDir}": ${(err as NodeJS.ErrnoException).message}\n` +
    `Set DATA_DIR to a writable location or create the directory manually.`
  );
  process.exit(1);
}

Should fix

3. Version reference says "v0.13.0+" but this will ship as 0.12.x

The Upgrading section header says ### Database path change (v0.13.0+) — should match whichever version this actually releases under.


Happy to push fixup commits for these if you'd like, or let me know if you'd prefer to address them yourself.

@cynthiateeters
Copy link
Copy Markdown
Contributor Author

Thanks for the offer to keep working the issue. I haven't done any open source contributing for a while and it's been fun to get back into it. I also use real-world scenarios like this with my JavaScript students — I stress that they need to work in a real developer environment with real tools, so being able to point to my own PRs as examples makes that lesson land better.

The try/catch on mkdirSync is a great catch — as someone who teaches JavaScript best practices around error handling, I especially appreciate that one.

I'll address all three items.

Copy link
Copy Markdown
Owner

@mkreyman mkreyman left a comment

Choose a reason for hiding this comment

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

All three items addressed cleanly. Thanks for the thorough work, @cynthiateeters!

@mkreyman mkreyman merged commit 02779a5 into mkreyman:master Mar 25, 2026
1 check passed
@cynthiateeters
Copy link
Copy Markdown
Contributor Author

You're very welcome 😎, @mkreyman

@cynthiateeters cynthiateeters deleted the fix/sqlite-cantopen-cwd branch March 26, 2026 13:30
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.

Server crashes with SQLITE_CANTOPEN when parent process CWD changes

2 participants