Skip to content

fix(kernel-store): move to better-sqlite3 13, which survives teardown on Node 24.20 - #1045

Merged
rekmarks-consensys-1 merged 2 commits into
rekmarks-consensys-1-patch-1from
sirtimid/better-sqlite3-node24
Sep 18, 2026
Merged

rekmarks-consensys-1 merged 2 commits into
rekmarks-consensys-1-patch-1from
sirtimid/better-sqlite3-node24

Conversation

@sirtimid

@sirtimid sirtimid commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

The failure

On Node 24.20.0, better-sqlite3 12.x aborts the process during shutdown:

node::RemoveEnvironmentCleanupHook(Isolate*, CleanupHook, void*) at ../src/api/hooks.cc:142
Assertion failed: (env) != nullptr
  Statement::~Statement() [better_sqlite3.node]

The destructor runs after the environment is gone and asserts on the way out. Everything it kills has already passed, so it surfaces as Worker exited unexpectedly rather than as a test failure anyone can read.

Nothing in this repository changed. CI's matrix floats on 24.x, and had not run since 2026-09-03, when the runner still resolved that to 24.19.0. It now resolves to 24.20.0.

It is not a missing close

The suites that hit this close their databases correctly. I narrowed it on 24.20.0:

Repro Result
Plain script, statement alive at exit, no close() clean
Vitest worker + real driver, database left open clean
Vitest worker + database + live worker thread clean
Full integration test aborts
Full integration test on Node 24.18.0 clean

Same code, same test, only the Node patch differs — which places it between the two Node releases rather than in our teardown.

The fix

13.x is a major, but it moves none of the surface this driver uses — prepare, run, get, all, iterate, pluck, transaction, exec, close — and its engines.node floor is >=22, the same one this package already declares.

Verified on Node 24.20.0 with the bump:

  • Unit suite: 53/53 tasks
  • Integration suite: all pass, no abort, no worker timeout
  • kernel-node-runtime e2e: went from 9 failures plus the abort to running normally
  • Node 22.23.2: kernel-store passes

One caveat, so nobody is surprised

remote-comms.test.ts > handles remote intentional disconnect without reconnecting fails locally for me, and it does so on 24.18.0, 24.19.0 and 24.20.0 alike, with and without this bump. It is flaky in my environment rather than related to either the Node bump or this change — I initially misread it as a second Node regression, then reproduced the failure on 24.18.0 twice in a row. Worth watching in CI, but it is not what this PR is about.

Why not pin Node instead

Pinning the matrix to a known-good patch would go green too, and hide this until the next time someone bumps Node. The floating 24.x is a separate reproducibility question worth having on its own terms; this is the actual defect.

Needs #1043 to land before CI here can run at all.

🤖 Generated with Claude Code


Note

Medium Risk
Major bump of a native SQLite dependency in the storage layer; API usage is unchanged but install/build and runtime behavior depend on the new binary and Node 22+.

Overview
Upgrades @metamask/kernel-store to better-sqlite3 ^13.0.3 so Node 24.20 no longer aborts during process teardown (Statement::~Statement / cleanup-hook assert with 12.x), which was showing up as unexplained Vitest worker deaths after tests passed.

The changelog marks this as BREAKING for the dependency (Node ≥22); that matches the package’s existing engines floor. No changes to the SQLite driver wrapper—only package.json, lockfile resolution (13.0.3, updated native build deps), and changelog notes.

Incidental edits: renovatebot workflow uses ubuntu-latest instead of ubuntu-24.04, plus small YAML/JSON formatting in that workflow and renovate.json.

Reviewed by Cursor Bugbot for commit b79417a. Bugbot is set up for automated code reviews on this repo. Configure here.

@socket-security

socket-security Bot commented Sep 8, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedbetter-sqlite3@​12.4.6 ⏵ 13.0.3100 +1210010090100

View full report

@sirtimid

sirtimid commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Folded into #1043. The two were blocking each other: #1043's jobs failed on the better-sqlite3 abort, and this PR failed at job setup on the action-pinning policy that #1043 fixes. Neither could go green alone, so the bump now rides on #1043.

@sirtimid sirtimid closed this Sep 8, 2026
@sirtimid
sirtimid deleted the sirtimid/better-sqlite3-node24 branch September 8, 2026 15:51
@sirtimid
sirtimid restored the sirtimid/better-sqlite3-node24 branch September 10, 2026 12:09
@sirtimid sirtimid reopened this Sep 10, 2026
@sirtimid
sirtimid requested a review from a team as a code owner September 10, 2026 12:09
@rekmarks-consensys-1
rekmarks-consensys-1 force-pushed the sirtimid/better-sqlite3-node24 branch from adfc6c4 to 497ef22 Compare September 18, 2026 16:05
… on Node 24.20

On Node 24.20.0, `better-sqlite3` 12.x aborts the process while it is shutting
down:

    node::RemoveEnvironmentCleanupHook(Isolate*, CleanupHook, void*)
      at ../src/api/hooks.cc:142
    Assertion failed: (env) != nullptr
    Statement::~Statement() [better_sqlite3.node]

The destructor runs after the environment is gone and asserts on the way out.
Everything it kills has already passed, so it reads as a worker dying rather
than as a test failure, and vitest reports only that the fork exited.

Not a missing `close`. The suites that hit it close their databases; a plain
script, a vitest worker holding an open database, and one holding an open
database plus a live worker thread are all clean on 24.20.0. It takes the whole
kernel to provoke, and the same code on 24.18.0 is clean, which places it
between the two Node releases rather than in this repository.

The tests never ran into it because CI floats on `24.x` and had not run since
2026-09-03, when the runner still resolved that to 24.19.0.

13.x is a major, but it moves none of the surface this driver uses -- `prepare`,
`run`, `get`, `all`, `iterate`, `pluck`, `transaction`, `exec`, `close` -- and
its Node floor is the one this package already sets. Verified on 24.20.0: the
unit suite, the integration suite, and the `kernel-node-runtime` e2e all run
without the abort, and kernel-store passes on 22.23.2.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@rekmarks-consensys-1
rekmarks-consensys-1 force-pushed the sirtimid/better-sqlite3-node24 branch from 497ef22 to 2f36acf Compare September 18, 2026 16:10
@rekmarks-consensys-1
rekmarks-consensys-1 changed the base branch from main to rekmarks-consensys-1-patch-1 September 18, 2026 16:16
@rekmarks-consensys-1
rekmarks-consensys-1 merged commit 8cbff59 into rekmarks-consensys-1-patch-1 Sep 18, 2026
5 checks passed
@rekmarks-consensys-1
rekmarks-consensys-1 deleted the sirtimid/better-sqlite3-node24 branch September 18, 2026 16:18
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 73.05%
🟰 ±0%
9790 / 13401
🔵 Statements 72.9%
🟰 ±0%
9954 / 13653
🔵 Functions 73.6%
🟰 ±0%
2301 / 3126
🔵 Branches 67.27%
🟰 ±0%
4023 / 5980
File CoverageNo changed files found.
Generated in workflow #4831 for commit b79417a by the Vitest Coverage Report Action

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