Bug Description
The memos-local-openclaw-plugin fails to load after OpenClaw or the plugin itself is updated, throwing:
Error: The module '/path/to/memos-local-openclaw-plugin/node_modules/better-sqlite3/build/Release/better_sqlite3.node'
was compiled against a different Node.js version using NODE_MODULE_VERSION 141.
This version of Node.js requires NODE_MODULE_VERSION 127.
Please try re-compiling or re-installing the module.
This happens because better-sqlite3 is a native C++ addon compiled at install time against the Node ABI of the npm installation environment, but the OpenClaw Gateway may run under a different Node.js version.
Environment
- Plugin: @memtensor/memos-local-openclaw-plugin v1.0.8–1.0.10
- better-sqlite3: ^12.6.3
- macOS (Darwin arm64)
- Node.js version that compiles the module (e.g., v22.x via npm)
- OpenClaw Gateway runtime: Node 25.9.0 (Homebrew Cellar)
Root Cause
- The plugin uses
better-sqlite3, a native C++ module that must be compiled against the exact Node.js ABI version used at runtime
postinstall.cjs detects the mismatch and runs npm rebuild better-sqlite3, but:
- The rebuild uses the npm / Node environment available in the postinstall script context, which may differ from the Gateway runtime's Node version
- The LaunchAgent that runs the OpenClaw Gateway has its own
PATH and may invoke a different Node binary than what npm rebuild uses
- Even after a successful rebuild, the mismatch can recur if OpenClaw updates its Node runtime or if the plugin is reinstalled
Steps to Reproduce
- Install/update the plugin (npm install or OpenClaw plugin update)
- Start the OpenClaw Gateway via LaunchAgent
- Plugin registration fails with the ABI mismatch error
- Manual
npm rebuild better-sqlite3 in the plugin dir may temporarily fix it, but the problem recurs
Suggested Fixes
Option A — In-process ABI check + rebuild (recommended)
Instead of relying on postinstall, the plugin should detect the ABI mismatch at runtime (in register() or service.start()) using process.versions.modules and validateNativeBinding(). If mismatched, run npm rebuild better-sqlite3 programmatically in a subprocess using the same Node binary that the Gateway is currently using (not whatever npm resolves on PATH):
// In plugin register/startup:
const currentNodeBinary = process.execPath; // Use THIS Node, not npm rebuild env
const { spawnSync } = require('child_process');
spawnSync(currentNodeBinary, ['npm', 'rebuild', 'better-sqlite3'], {
cwd: pluginDir,
stdio: 'pipe',
});
Option B — Ship prebuilt binaries for all Node major versions
Use @mapbox/node-pre-gyp or prebuild-install to bundle prebuilt .node binaries for Node 22 and 25 on both darwin-arm64 and linux-x64, so the plugin never needs to compile at install time.
Option C — Document Node version pinning
Add a clear note in README + installation docs recommending that users pin the same Node major version for both the npm installation environment and the Gateway service. Provide instructions for locking Node via nvm or Homebrew services.
Workaround (temporary)
Manually rebuild using the same Node binary that the Gateway uses:
cd ~/.openclaw/extensions/memos-local-openclaw-plugin
/opt/homebrew/opt/node/bin/node /opt/homebrew/opt/node/bin/npm rebuild better-sqlite3
# Then restart gateway
launchctl kickstart -k gui/$(id -u)/ai.openclaw.gateway
But this needs to be repeated every time the plugin or OpenClaw is updated.
Priority
This is a blocking issue for any user whose OpenClaw Gateway runs under Node 25, which is the default Homebrew Cellar version on macOS. Given that Node 22 is LTS and Node 25 is the current macOS default for Homebrew users, this likely affects a significant portion of users.
Bug Description
The memos-local-openclaw-plugin fails to load after OpenClaw or the plugin itself is updated, throwing:
This happens because
better-sqlite3is a native C++ addon compiled at install time against the Node ABI of the npm installation environment, but the OpenClaw Gateway may run under a different Node.js version.Environment
Root Cause
better-sqlite3, a native C++ module that must be compiled against the exact Node.js ABI version used at runtimepostinstall.cjsdetects the mismatch and runsnpm rebuild better-sqlite3, but:PATHand may invoke a different Node binary than whatnpm rebuildusesSteps to Reproduce
npm rebuild better-sqlite3in the plugin dir may temporarily fix it, but the problem recursSuggested Fixes
Option A — In-process ABI check + rebuild (recommended)
Instead of relying on postinstall, the plugin should detect the ABI mismatch at runtime (in
register()orservice.start()) usingprocess.versions.modulesandvalidateNativeBinding(). If mismatched, runnpm rebuild better-sqlite3programmatically in a subprocess using the same Node binary that the Gateway is currently using (not whatever npm resolves on PATH):Option B — Ship prebuilt binaries for all Node major versions
Use
@mapbox/node-pre-gyporprebuild-installto bundle prebuilt.nodebinaries for Node 22 and 25 on both darwin-arm64 and linux-x64, so the plugin never needs to compile at install time.Option C — Document Node version pinning
Add a clear note in README + installation docs recommending that users pin the same Node major version for both the npm installation environment and the Gateway service. Provide instructions for locking Node via nvm or Homebrew services.
Workaround (temporary)
Manually rebuild using the same Node binary that the Gateway uses:
But this needs to be repeated every time the plugin or OpenClaw is updated.
Priority
This is a blocking issue for any user whose OpenClaw Gateway runs under Node 25, which is the default Homebrew Cellar version on macOS. Given that Node 22 is LTS and Node 25 is the current macOS default for Homebrew users, this likely affects a significant portion of users.