Skip to content

Memory MCP/CLI abort on Node 24.19–24.21: agentdb's better-sqlite3 11.x (RemoveEnvironmentCleanupHook … (env) != nullptr) #4055

Closed

Description

@ronmikailov

Environment: ruflo 3.56.1 and 3.56.3 (global npm), agentdb 3.0.0-alpha.20 (nested better-sqlite3 11.10.0), Node v24.21.0, Linux x64 (WSL2).

Symptom: the first memory call in a process (MCP memory_stats/memory_search, CLI memory search, hooks session-end) intermittently aborts:

node::RemoveEnvironmentCleanupHook(v8::Isolate*, CleanupHook, void*) at ../src/api/hooks.cc:142
Assertion failed: (env) != nullptr
 4: Database::~Database() [.../agentdb/node_modules/better-sqlite3/build/Release/better_sqlite3.node]

Through the ruflo-core plugin launcher the MCP server dies and Claude Code reports Connection closed, dropping all ruflo tools for the rest of the session. One real session: server idle 41 min, then its first memory_stats died, so this is not a startup race.

Cause: Node regression nodejs/node#65446: legacy node::ObjectWrap addons BUILT against ≥ 24.19.0 headers abort in GC finalizers. The fix landed as abe1b673e9b (PR #65943, 2026-09-21) but is not in any release through v24.21.0.

Evidence (A/B on the same store, Node 24.21.0): original binaries aborted 8/22 runs; the same binaries rebuilt against 24.18.1 headers aborted 0/17 (and 0/10 more through the plugin launcher after a 3.56.3 reinstall).

Ask:

  1. ruflo doctor: flag native addons whose build/config.gypi nodedir is ≥ 24.19 while the runtime is a 24.x without the fix.
  2. Document the workaround: node-gyp rebuild --release --nodedir=<24.18.1 headers> in each better-sqlite3 dir (agentdb-nested, top-level, agentic-flow).
  3. Longer term: agentdb on better-sqlite3 13.x (node-addon-api) removes the legacy ObjectWrap path.

Activity

  1. added a commit that references this issue on Oct 11, 2026
  2. ruvnet commented on Oct 11, 2026

    @ruvnet
    Owner

    Thanks @ronmikailov, this was a precise report. What is done and what is not:

    Shipped in #4069 (next @claude-flow/cli release): ruflo doctor (and doctor --component native-addon) now reads build/config.gypi of each better-sqlite3 copy in the resolved tree and warns when a locally compiled copy used Node 24.19+ headers while the runtime is Node 24.19-24.21, listing each path and version with the workarounds (Node 22 / 24.18.1 / a release with the fix, rebuild against 24.18.1 headers, or the 12.x prebuilt). It never loads an addon. The workaround is also in docs/USERGUIDE.md.

    Already shipped earlier (#3955, in 3.56.4+): ruflo opens AgentDB with its own prebuilt 12.x better-sqlite3, which keeps the source-built 11.x addon out of that code path.

    Verified: a clean install of [email protected] still contains nested agentdb/node_modules/better-sqlite3 and agentic-flow/node_modules/better-sqlite3 at 11.10.0 (agentdb 3.0.0-alpha.20 declares it as an optional dependency ^11.8.1), and the overrides in the ruflo wrapper do not apply to an installed package.

    Not verified / not done: I did not reproduce the abort (this machine runs Node 22; I did not install Node 24), so I am relying on your A/B (8/22 aborts with the original binaries, 0/17 rebuilt against 24.18.1 headers). The nested 11.x copies cannot be removed from inside the published package; the real fix is an agentdb release depending on better-sqlite3@^12, which is a separate repo and a maintainer decision. The upper bound of the check (24.21.x) should be revisited when a Node release ships fix (nodejs/node PR #65943).

  3. added a commit that references this issue on Oct 11, 2026
  4. ronmikailov commented on Oct 15, 2026

    @ronmikailov
    Author

    Follow-up: Node v24.22.0 (2026-10-14, LTS) ships the runtime fix, abe1b673e9 "src: keep global list of addon-provided cleanup hooks" (doc/changelogs/CHANGELOG_V24.md, credited to nodejs/node#63985; #65943, which doctor-native-addon.js cites, is its v24.x backport).

    A/B on ruflo 3.56.10 (WSL2, x64), 30 serial ruflo memory store --path <scratch> runs per arm. LD_DEBUG shows the command loads only ruflo/node_modules/better-sqlite3 (12.11.1):

    better-sqlite3 binary runtime aborts ((env) != nullptr, exit 134)
    12.11.1 compiled from source on 24.21.0 headers v24.21.0 21/30
    same binary v24.22.0 0/30
    stock npm i -g [email protected] on 24.22.0 (12.11.1 prebuilt) v24.22.0 0/30
    the same stock 12.11.1 prebuilt v24.21.0 0/30

    The prebuilt never aborted, so rows 3-4 show the stock install is healthy, not the fix; rows 1-2 are the A/B. So isAffectedNodeVersion()'s upper bound (v[1] <= 21) is right, and the fix is runtime-only: on 24.22.0 a binary built against 24.21.0 headers no longer aborts. Two suggestions for the FIX text:

    nodejs/node#65446 is still open upstream.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions