Skip to content

fix: install failed in deepseek harness desktop #2439

Closed

Description

@ushaio

Pre-submission checklist | 提交前检查

  • I have searched existing issues and this hasn't been mentioned before | 我已搜索现有问题,确认此问题尚未被提及
  • I have read the project documentation and confirmed this issue doesn't already exist | 我已阅读项目文档并确认此问题尚未存在
  • This issue is specific to MemOS and not a general software issue | 该问题是针对 MemOS 的,而不是一般软件问题

Bug Description | 问题描述

✓ Lockfile passes supply-chain policies (verified 11h ago)
Progress: resolved 1, reused 0, downloaded 0, added 0
[WARN] 3 deprecated subdependencies found: boolean@3.2.0, ini@1.3.0, prebuild-install@7.1.3
[WARN] Issues with peer dependencies found. Run "pnpm peers check" to list them.

dependencies:

  • @memtensor/memos-local-plugin ^2.0.20

Packages: -51

Progress: resolved 154, reused 51, downloaded 0, added 0, done
node_modules/protobufjs postinstall$ node scripts/postinstall
node_modules/onnxruntime-node postinstall$ node ./script/install
node_modules/esbuild postinstall$ node install.js
node_modules/sharp install$ node install/check.js || npm run build
node_modules/better-sqlite3 install$ prebuild-install || node-gyp rebuild --release
node_modules/protobufjs postinstall: Done
node_modules/sharp install: Done
node_modules/better-sqlite3 install: (node:259528) [DEP0176] DeprecationWarning: fs.R_OK is deprecated, use fs.constants.R_OK instead
node_modules/better-sqlite3 install: (Use DeepSeek Harness --trace-deprecation ... to show where the warning was created)
node_modules/onnxruntime-node postinstall: Done
node_modules/esbuild postinstall: Done
node_modules/better-sqlite3 install: prebuild-install warn install No prebuilt binaries found (target=24.18.1 runtime=node arch=x64 libc= platform=win32)
node_modules/better-sqlite3 install: C:\Users\Administrator.dsh\profiles\desktop\node_modules\better-sqlite3>if not defined npm_config_node_gyp (node "D:\AI\DeepSeek-Harness\resources\runtime\pnpm\dist\node-gyp-bin\..\node_modules\node-gyp\bin\node-gyp.js" rebuild --release ) else (node "D:\AI\DeepSeek-Harness\resources\runtime\pnpm\dist\node_modules\node-gyp\bin\node-gyp.js" rebuild --release )
node_modules/better-sqlite3 install: gyp info it worked if it ends with ok
node_modules/better-sqlite3 install: gyp info using node-gyp@12.4.0
node_modules/better-sqlite3 install: gyp info using node@24.18.1 | win32 | x64
node_modules/better-sqlite3 install: gyp info find Python using Python version 3.12.5 found at "D:\DevKit\Python\Python312\python.exe"
node_modules/better-sqlite3 install: gyp info find VS using VS2022 (17.14.37531.7) found at:
node_modules/better-sqlite3 install: gyp info find VS "C:\Program Files\Microsoft Visual Studio\2022\Community"
node_modules/better-sqlite3 install: gyp info find VS run with --verbose for detailed information
node_modules/better-sqlite3 install: gyp info spawn D:\DevKit\Python\Python312\python.exe
node_modules/better-sqlite3 install: gyp info spawn args [
node_modules/better-sqlite3 install: gyp info spawn args 'D:\AI\DeepSeek-Harness\resources\runtime\pnpm\dist\node_modules\node-gyp\gyp\gyp_main.py',
node_modules/better-sqlite3 install: gyp info spawn args 'binding.gyp',
node_modules/better-sqlite3 install: gyp info spawn args '-f',
node_modules/better-sqlite3 install: gyp info spawn args 'msvs',
node_modules/better-sqlite3 install: gyp info spawn args '-I',
node_modules/better-sqlite3 install: gyp info spawn args 'C:\Users\Administrator\.dsh\profiles\desktop\node_modules\better-sqlite3\build\config.gypi',
node_modules/better-sqlite3 install: gyp info spawn args '-I',
node_modules/better-sqlite3 install: gyp info spawn args 'D:\AI\DeepSeek-Harness\resources\runtime\pnpm\dist\node_modules\node-gyp\addon.gypi',
node_modules/better-sqlite3 install: gyp info spawn args '-I',
node_modules/better-sqlite3 install: gyp info spawn args 'C:\Users\Administrator\AppData\Local\node-gyp\Cache\24.18.1\include\node\common.gypi',
node_modules/better-sqlite3 install: gyp info spawn args '-Dlibrary=shared_library',
node_modules/better-sqlite3 install: gyp info spawn args '-Dvisibility=default',
node_modules/better-sqlite3 install: gyp info spawn args '-Dnode_root_dir=C:\Users\Administrator\AppData\Local\node-gyp\Cache\24.18.1',
node_modules/better-sqlite3 install: gyp info spawn args '-Dnode_gyp_dir=D:\AI\DeepSeek-Harness\resources\runtime\pnpm\dist\node_modules\node-gyp',
node_modules/better-sqlite3 install: gyp info spawn args '-Dnode_lib_file=C:\\Users\\Administrator\\AppData\\Local\\node-gyp\\Cache\\24.18.1\\<(target_arch)\\node.lib',
node_modules/better-sqlite3 install: gyp info spawn args '-Dmodule_root_dir=C:\Users\Administrator\.dsh\profiles\desktop\node_modules\better-sqlite3',
node_modules/better-sqlite3 install: gyp info spawn args '-Dnode_engine=v8',
node_modules/better-sqlite3 install: gyp info spawn args '--depth=.',
node_modules/better-sqlite3 install: gyp info spawn args '--no-parallel',
node_modules/better-sqlite3 install: gyp info spawn args '--generator-output',
node_modules/better-sqlite3 install: gyp info spawn args 'C:\Users\Administrator\.dsh\profiles\desktop\node_modules\better-sqlite3\build',
node_modules/better-sqlite3 install: gyp info spawn args '-Goutput_dir=.'
node_modules/better-sqlite3 install: gyp info spawn args ]
node_modules/better-sqlite3 install: gyp: name 'enable_thin_lto' is not defined while evaluating condition 'enable_thin_lto=="true"' in binding.gyp while trying to load binding.gyp
node_modules/better-sqlite3 install: gyp ERR! configure error
node_modules/better-sqlite3 install: gyp ERR! stack Error: gyp failed with exit code: 1
node_modules/better-sqlite3 install: gyp ERR! stack at ChildProcess. (D:\AI\DeepSeek-Harness\resources\runtime\pnpm\dist\node_modules\node-gyp\lib\configure.js:317:18)
node_modules/better-sqlite3 install: gyp ERR! stack at ChildProcess.emit (node:events:509:28)
node_modules/better-sqlite3 install: gyp ERR! stack at ChildProcess._handle.onexit (node:internal/child_process:295:12)
node_modules/better-sqlite3 install: gyp ERR! System Windows_NT 10.0.26200
node_modules/better-sqlite3 install: gyp ERR! command "D:\AI\DeepSeek-Harness\DeepSeek Harness.exe" "D:\AI\DeepSeek-Harness\resources\runtime\pnpm\dist\node_modules\node-gyp\bin\node-gyp.js" "rebuild" "--release"
node_modules/better-sqlite3 install: gyp ERR! cwd C:\Users\Administrator.dsh\profiles\desktop\node_modules\better-sqlite3
node_modules/better-sqlite3 install: gyp ERR! node -v v24.18.1
node_modules/better-sqlite3 install: gyp ERR! node-gyp -v v12.4.0
node_modules/better-sqlite3 install: gyp ERR! $npm_package_name better-sqlite3
node_modules/better-sqlite3 install: gyp ERR! $npm_package_version 12.11.1
node_modules/better-sqlite3 install: gyp ERR! not ok
node_modules/better-sqlite3 install: Failed
[ELIFECYCLE] Command failed with exit code 1.

How to Reproduce | 如何重现

Image Image

Environment | 环境信息

deepseek harness desktop:V0.2.0-rc.2

Additional Context | 其他信息

No response

Willingness to Implement | 实现意愿

  • I'm willing to implement this myself | 我愿意自己解决
  • I would like someone else to implement this | 我希望其他人来解决

Root cause analysis (appended after triage)

TL;DR — This is not a bug in MemOS's own code. It happens in the native-dependency build path of @memtensor/memos-local-plugin when that build runs inside the DeepSeek Harness Electron runtime: better-sqlite3 finds no prebuilt binary, falls back to a source build, and node-gyp then aborts because the gyp config it generates carries Electron's build variables — which have no enable_thin_lto key — while Node 24.18.1's common.gypi unconditionally reads that variable on Windows. There is a second, independent blocker behind it (ABI 137 vs 149), so silencing the gyp error alone is not enough.

Environment (measured on the reporting machine, read-only)

Component Value
DSH desktop 0.2.0-rc.2
Runtime that runs pnpm/node-gyp DeepSeek Harness.exe = Electron 44.0.0 (via ELECTRON_RUN_AS_NODE)
Node / ABI node 24.18.1, process.versions.modules = 149, napi 10, sqlite 3.53.1
pnpm / node-gyp pnpm 11.7.0, node-gyp 12.4.0
Packages involved @memtensor/memos-local-plugin@2.0.20 → better-sqlite3@12.11.1, prebuild-install@7.1.3, node-abi@3.96.0
Native toolchain present Python 3.12.5, Visual Studio 2022 17.14 — so this is not a missing-compiler problem

Step 1 — no prebuilt binary is found

better-sqlite3's install script is prebuild-install || node-gyp rebuild --release. prebuild-install@7.1.3 defaults to runtime = 'node' and target = process.versions.node (24.18.1), then asks node-abi for the ABI. node-abi@3.96.0 short-circuits:

if (runtime === 'node') {
  if (!target) return process.versions.modules
  if (target === process.versions.node) return process.versions.modules
}

Inside the Electron process this returns 149 (Electron's ABI) instead of Node 24's 137, so it requests an asset named ...-node-v149-win32-x64, which cannot exist → No prebuilt binaries found (target=24.18.1 runtime=node arch=x64 libc= platform=win32). This cannot be worked around with flags as long as the runtime is Electron: prebuild-install recomputes the ABI unconditionally, and every target equal to process.versions.node resolves to Electron's ABI.

Step 2 — the source build fails (the reported error)

node-gyp 12.4.0 then runs in that same Electron process. It downloads the Node 24.18.1 headers and passes -I ...\include\node\common.gypi, but since neither --nodedir nor --dist-url is set, create-config-gypi.js falls back to process.config, so the generated build/config.gypi contains Electron's build variables:

Variable generated build/config.gypi (Electron) headers include/node/config.gypi (Node 24.18.1)
enable_lto "true" "false"
enable_thin_lto absent "false"
v8_enable_pointer_compression 1 0
v8_enable_sandbox 1 0
node_module_version 149 137

Node 24.18.1's common.gypi (Windows branch, evaluated while the file is loaded) contains both LTO conditions:

['enable_lto=="true"', { ... }],
['enable_thin_lto=="true"', { ... }],

gyp requires any variable used in a condition to be defined; an undefined variable is a hard error, not false:

gyp: name 'enable_thin_lto' is not defined while evaluating condition
'enable_thin_lto=="true"' in binding.gyp while trying to load binding.gyp

The in binding.gyp part is only gyp's attribution to the build file being loaded — the condition itself lives in Node's common.gypi, which every binding.gyp pulls in via -I. better-sqlite3's own binding.gyp contains no thin_lto reference (verified), so there is nothing to patch there either.

This is invisible in normal Node usage for two reasons: a real Node binary's process.config.variables does define enable_thin_lto, and when --nodedir/--dist-url is passed node-gyp reads the headers' config.gypi, which also defines it. Related upstream report on the same variable, in a different failure mode (thin-LTO flags leaking into an MSVC project, not an undefined variable): nodejs/node#64674. The same failure shape applies to any node-gyp-built native dependency installed through DSH desktop, not just this one.

Step 3 — even a successful compile would not load

better-sqlite3 is a V8-ABI addon (NODE_MODULE_INIT, so it registers as node_register_module_v137 with these headers), while the DSH host process requires ABI 149. If gyp were fixed without changing the headers, require('better-sqlite3') would still fail with the usual "compiled against a different Node.js version" error. Only a build against the Electron 44 headers can load in this host.

Result on disk

pnpm exits with [ELIFECYCLE] Command failed with exit code 1 and rolls the install back: the profile package.json and pnpm-lock.yaml have no @memtensor entry, while leftovers remain (empty node_modules/@memtensor/, half-written node_modules/better-sqlite3/build/config.gypi). An earlier attempt of the same install stopped one step before this, at [ERR_PNPM_IGNORED_BUILDS] — pnpm does not run dependency build scripts until they are approved, and approving them is what exposes this failure.

Possible directions (not validated end-to-end here)

Plugin / package side:

  • Do not depend on compiling a V8-ABI addon on the client: ship prebuilt binaries per platform/ABI (Electron 44 → ABI 149), or make the prebuild lookup runtime-aware.
  • Or switch the local storage layer to something ABI-stable: a Node-API module, or node:sqlite — the DSH Electron 44 runtime embeds Node 24.18.1 with SQLite (process.versions.sqlite = 3.53.1).

Client / install side (the actual fix for DSH desktop):

  • Install profile dependencies with Electron headers, i.e. electron-rebuild semantics: npm_config_runtime=electron, npm_config_target=44.0.0, npm_config_disturl=https://electronjs.org/headers. node-gyp then reads the Electron headers' config.gypi (which defines enable_thin_lto) and produces ABI-149 binaries.

Minimal unblock for the gyp error only (does not fix the ABI mismatch):

  • Set npm_config_nodedir=<node-gyp cache>\24.18.1 or npm_config_disturl=https://nodejs.org/download/release/, so create-config-gypi.js reads the Node headers' config.gypi, which has enable_thin_lto: "false".

How this was determined

Read-only inspection on the reporting machine, without modifying the plugin: the DSH profile (package.json, pnpm-lock.yaml, .plugin-manager/logs/operation-*/pnpm.log), the installed better-sqlite3/binding.gyp and generated build/config.gypi, prebuild-install/rc.js, node-abi/index.js, node-gyp's create-config-gypi.js, and Node 24.18.1's cached common.gypi / config.gypi; plus running ELECTRON_RUN_AS_NODE=1 "DeepSeek Harness.exe" -e "..." to print process.versions and process.config.variables — which reports enable_lto: true and confirms the enable_thin_lto key is absent.

中文摘要

根因:不是 MemOS 自身代码的问题,而是插件的原生依赖在 DSH 桌面端的 Electron 运行时里编译不了。

  1. @memtensor/memos-local-plugin@2.0.20 依赖 better-sqlite3@12.11.1;DSH 用自带的 Electron(DeepSeek Harness.exe,Electron 44.0.0 / 内嵌 Node 24.18.1 / ABI 149)充当 Node 来跑 pnpm 和 node-gyp。
  2. 预编译包没命中:prebuild-install 默认 runtime=node、target=24.18.1,而 node-abi 有个快捷分支 —— target === process.versions.node 时直接返回 process.versions.modules,在 Electron 进程里是 149(Node 24 实际是 137),于是它去找根本不存在的 node-v149 产物。
  3. 源码编译报错的原因:node-gyp 没收到 --nodedir/--dist-url,生成的 build/config.gypi 取的是 Electron 的 process.config —— 有 enable_lto: "true",但完全没有 enable_thin_lto 这个键;而 Node 24.18.1 的 common.gypi 在 Windows 分支上会直接判断 enable_thin_lto=="true",gyp 要求条件变量必须已定义,未定义就直接 fatal 退出。报错里的 "in binding.gyp" 只是 gyp 对当前加载文件的归属描述(common.gypi 是通过 -I 被包含进来的),better-sqlite3 自己的 binding.gyp 里没有 thin_lto。
  4. 还有第二层问题:即便编译通过,产物是按 Node 24.18.1 头文件(ABI 137)编译的,宿主 Electron 44 需要 149,require() 仍会报 ABI 不匹配,必须用 Electron 头文件编译才能真正加载。
  5. 结果:pnpm 以 ELIFECYCLE 退出并回滚(profile 的 package.json/pnpm-lock.yaml 里已没有 @memtensor,只留下空目录和半成品的 build 目录);再往前一次尝试是卡在 ERR_PNPM_IGNORED_BUILDS(pnpm 需先批准依赖的构建脚本),批准后才暴露出这个编译失败。

修复建议:插件侧最好别依赖客户端源码编译(按 ABI 提供预编译产物,或改用 Node-API / node:sqlite);DSH 侧安装 profile 依赖时应按 electron-rebuild 的方式带 npm_config_runtime=electron、npm_config_target=44.0.0、npm_config_disturl=https://electronjs.org/headers。只绕过 gyp 报错(不解决 ABI)可传 npm_config_nodedir/npm_config_disturl,让 node-gyp 读 Node 头文件里那份定义了 enable_thin_lto: "false" 的 config.gypi。


Related issues and an upstream fix (update)

Duplicate check

Searched this repo and GitHub-wide for the error in this report — there is no exact duplicate: this is currently the only issue carrying enable_thin_lto is not defined / ELIFECYCLE for a DSH desktop plugin install. What exists instead is a recurring family of better-sqlite3 native-module reports, all from other clients or other Node majors, and all closed:

Issue State Why it is not a duplicate
#1734 CLOSED/COMPLETED better-sqlite3 ABI mismatch on Node 25; fixed by upgrading better-sqlite3 to 12.10.0 so that Node 25 prebuilds exist. Here the version is already 12.11.1, and the ABI is resolved from Electron (149), so upgrading the package alone cannot help.
#1343 CLOSED/COMPLETED Windows ABI mismatch, manual rebuild required; fixed by #2049, released in v2.0.23.
#1296 CLOSED/NOT_PLANNED Windows first-start missing binding; auto-closed for inactivity.
#1258, #1201, #1192, #1358, #1199 CLOSED Could not locate the bindings file / Windows path resolution — same loading stage, different cause.
#1639 CLOSED Memory Viewer not starting on Node 24 — again a Node-major change breaking the native module.
#2160 OPEN Viewer fails to start on Ubuntu 24.04 + Hermes; its better-sqlite3 rebuild succeeds, so the root cause differs — but the "broken semi-installed state, needs manual cleaning up" it reports matches the rollback leftovers described above, so the two are worth cross-referencing.
#2437, #2405, #2407 OPEN Also DSH desktop, but unrelated defects (aborted turns, session format v4).
#1545 CLOSED npm install -g answered 404 because the package was not published to npm yet — unrelated.

Upstream, only nodejs/node#64674 mentions the same gyp variable — a different failure mode (thin-LTO flags leaking into an MSVC project → LNK1117, not an undefined variable); closed 2026-07-22.

Cleaner fix for the gyp error: node-gyp >= 13.0.0

nodejs/node-gyp#3331 ("fix: disable LTO for addon builds on Windows", merged 2026-06-10, first released in v13.0.0 on 2026-06-12) added this to lib/create-config-gypi.js:

// disable LTO for addon builds. node release builds may enable (thin) LTO,
variables.enable_lto = 'false'
variables.enable_thin_lto = 'false'

With node-gyp >= 13.0.0 the generated build/config.gypi therefore always defines enable_thin_lto, and the failure reported here cannot occur. DSH desktop bundles node-gyp 12.4.0 (released 2026-06-05), whose create-config-gypi.js contains no such lines — it misses the fix by seven days. Upgrading the bundled node-gyp to >= 13 is thus the most direct client-side remedy, and it supersedes the npm_config_nodedir / npm_config_disturl workaround suggested above. Neither of them fixes the ABI mismatch in Step 3, which still requires Electron headers.

中文摘要

重复性排查:全站搜索后确认——没有重复 issue。#2439 是目前唯一带 enable_thin_lto is not defined / ELIFECYCLE 报错的 issue;仓库里只有一批 better-sqlite3 原生模块的"家族史":#1734(Node 25 ABI 不匹配,靠升级 better-sqlite3 到 12.10.0 修好)、#1343(Windows ABI,由 #2049 修复并在 v2.0.23 发布)、#1296(Windows 缺 binding,无响应被自动关闭)、#1258/#1201/#1192/#1358/#1199(bindings 找不到 / Windows 路径解析)、#1639(Node 24 上 viewer 不启动)。其中 #2160 仍处于打开状态(Ubuntu/Hermes,rebuild 成功但 viewer 起不来),根因不同,但它描述的"半安装残留、需要手动清理"与本 issue 的回滚残留一致,值得互引。DSH 相关的 #2437/#2405/#2407 是别的问题;#1545 是当年包还没上 npm 的 404。上游只有 nodejs/node#64674 提到同一变量,但那是另一种失效模式(thin-LTO 参数注入 MSVC 工程导致 LNK1117),已于 2026-07-22 关闭。

更干净的修法:node-gyp ≥ 13.0.0(nodejs/node-gyp#3331,2026-06-10 合并,v13.0.0 于 2026-06-12 发布)在 lib/create-config-gypi.js 里显式写死 variables.enable_lto = 'false'、variables.enable_thin_lto = 'false',因此升级后生成的 build/config.gypi 一定带这个变量,本 issue 的报错不会再出现。DSH 内置的是 node-gyp 12.4.0(2026-06-05 发布),差 7 天没吃到这个修复。这是客户端侧最直接的解法,比正文里 npm_config_nodedir/disturl 的绕法更干净;不过两者都不解决第 3 步的 ABI 137/149 不匹配,那一层仍必须用 Electron 头文件编译。

Activity

  1. added
    status:needs-triageNeeds initial triage | 需要初步判断 & 问题复现
    types:bugSomething isn't working | 功能异常
    on Sep 30, 2026
  2. Lartorias commented on Sep 30, 2026

    @Lartorias

    是的遇到同样问题, desktop无法使用,web正常

  3. liangl1985 commented on Oct 6, 2026

    @liangl1985

    Same symptom here, and we found a fix that needs no compiler.

    Root cause

    • The host is Electron-based (DSH Desktop → Electron 44, i.e. NODE_MODULE_VERSION 149).
    • better-sqlite3@12.11.1 ships prebuilds only up to electron-v146 for win32-x64; prebuild-install then falls back to node-gyp rebuild, which fails without Visual Studio — and even when run under plain Node it fetches the node ABI artifact, not the Electron one.
    • The adapter fails while loading better_sqlite3.node. Since failOnStartupError defaults to false, it degrades silently: no Viewer on :18801, no memos_* tools, empty data/ — it looks like the plugin was never installed.

    Fix (verified on Windows + Electron 44 / ABI 149)
    better-sqlite3@13 is the first N-API release — from its v13.0.0 notes: "prebuilt binaries should theoretically work across different versions of Node.js and Electron" — and it ships every prebuild inside the npm package, including prebuilds/win32-x64.node. Two lines in the profile:

    # $DSH_HOME/profiles/<profile>/pnpm-workspace.yaml
    overrides:
      better-sqlite3: 13.0.3
    allowBuilds:
      'better-sqlite3@13.0.3': false   # see note below

    allowBuilds must be false for this package: with true, pnpm runs the default node-gyp rebuild because the package carries a binding.gyp, and that fails without a toolchain. v13 needs no build step — the N-API prebuild is already in the package.

    Result after restarting the profile
    12 SQLite migrations applied → pipeline.ready → http://127.0.0.1:18801 listening → memos_* tools registered.

    Debug tip
    Temporarily set failOnStartupError: true on the memos-local-memory row (keep all 13 fields — the patch layer replaces the whole config object). Otherwise this class of startup failure stays invisible.

    Suggestion
    Consider bumping better-sqlite3 to ^13 (or documenting this override) so Electron-based hosts work out of the box.

  4. TankTechnology commented on Oct 13, 2026

    @TankTechnology

    Confirming this on macOS arm64 with the official DeepSeek Harness.app (Electron 44 / NODE_MODULE_VERSION 149), plus a dependency-level finding that I believe is the actual fix.

    Reproduction

    Installing @memtensor/memos-local-plugin@2.0.20 into a DSH profile, mirroring the one-command installer's reviewed build policy (better-sqlite3, esbuild, sharp allowed; onnxruntime-node, protobufjs and the package's own postinstall denied):

    node_modules/better-sqlite3 install$ prebuild-install || node-gyp rebuild --release
    node_modules/better-sqlite3 install: prebuild-install warn install No prebuilt binaries found
      (target=24.18.1 runtime=node arch=arm64 libc= platform=darwin)
    node_modules/better-sqlite3 install: gyp info using node@24.18.1 | darwin | arm64
    node_modules/better-sqlite3 install: gyp: No Xcode or CLT version detected!
    node_modules/better-sqlite3 install: gyp ERR! configure error
    node_modules/better-sqlite3 install: gyp ERR! not ok
    node_modules/better-sqlite3 install: Failed
    [ELIFECYCLE] Command failed with exit code 1.
    

    End state: the package is on disk and registered in the profile, but no build/Release/ and no *.node exist anywhere, so

    require('better-sqlite3')  ->  Error: Could not locate the bindings file.
    

    With failOnStartupError: false this matches the silent degradation described above — no Viewer on :18801, no memos_* tools, empty data/ — and it looks like the plugin was never installed.

    Why no prebuild is found: the dependency pin

    @memtensor/memos-local-plugin@2.0.20 declares better-sqlite3: ^12.10.0, resolving to 12.11.1. Its darwin-arm64 prebuilds cover:

    • electron-v121 … electron-v146
    • node-v127, node-v137, node-v141, node-v147

    There is no electron-v149 and no node-v149. DSH Desktop runs plugin installs through the Electron binary itself:

    Command failed with exit code 1: '/Applications/DeepSeek Harness.app/Contents/MacOS/DeepSeek Harness'
      --expose-internals '.../runtime/pnpm/bin/pnpm.mjs' add '@memtensor/memos-local-plugin@2.0.20'
    

    Since node-v137-darwin-arm64 does exist and was not taken, the resolver is keying off ABI 149. That is why any Electron-hosted DSH install misses the prebuild and falls through to node-gyp.

    Verified fix direction

    better-sqlite3@13.0.0 release notes (2026-07-21):

    Version 13.0.0 marks a major milestone, as it's the first version of better-sqlite3 to run on the N-API. This means prebuilt binaries should theoretically work across different versions of Node.js and Electron... we've removed the deprecated prebuild-install dependency, and now prebuilt binaries are published directly with the better-sqlite3 code itself.

    Bumping the pin from ^12.10.0 to ^13.0.0 should remove the ABI coupling entirely, instead of requiring a compiler toolchain on every Electron host.

    Environment notes

    • DSH Desktop bundle: Node 24.18.1, pnpm 11.7.0, Electron 44.0.0, process.versions.modules = 149, darwin/arm64.
    • Port :18801 was free throughout, so a missing Viewer is not a port conflict.
    • The desktop profile is app-owned; the shipped CLI refuses it (profile "desktop" is managed exclusively by the Electron application), so the app's own plugin entry point is the only install path there. Worth stating next to the --profile web instructions.
    • The node-gyp fallback also needs Xcode/CLT on macOS, which many hosts will not have. The ^13 bump avoids depending on it at all.
  5. TankTechnology commented on Oct 13, 2026

    @TankTechnology

    Follow-up with an end-to-end validation of a candidate fix, since the dependency-level analysis above suggests one.

    TL;DR

    Bumping better-sqlite3 from ^12.10.0 to ^13.0.3 makes the adapter install in a single pass on the same host that fails today, with no compiler and no ABI coupling.

    Note: prefer ^13.0.3 over ^13.0.0 — 13.0.1 fixed a parameter-binding regression in 13.0.0 where binding became overly strict and rejected plain objects from other realms.

    Why v13 removes the problem entirely

    better-sqlite3@13.0.3 ships the binaries inside the package:

    node_modules/better-sqlite3/prebuilds/
      darwin-arm64.node  darwin-x64.node
      linux-arm64.node   linux-x64.node   linuxmusl-arm64.node  linuxmusl-x64.node
      win32-arm64.node   win32-x64.node
    
    • no install script at all (v12 had prebuild-install || node-gyp rebuild --release)
    • "gypfile": false
    • dependencies: only node-addon-api (prebuild-install is gone)

    Because these are N-API, there is no per-ABI variant, so an Electron host does not need a matching electron-vXXX artifact.

    Verified on the failing host

    Host: macOS arm64, DSH Desktop bundle — Electron 44.0.0, Node 24.18.1, pnpm 11.7.0, process.versions.modules = 149.

    Direct load and functional test under that ABI, with no build approved and no compiler present:

    ABI in use: 149 | electron 44.0.0
    rows: 3 | iterated: 3
    sqlite: 3.53.4
    

    (WAL pragma, DDL, transaction, insert, iterate, count, close.)

    Full plugin install, with overrides: better-sqlite3: ^13.0.0 in the profile's pnpm-workspace.yaml and the allowBuilds policy from your README seeded before the first attempt:

    dsh plugin --profile web add @memtensor/memos-local-plugin@2.0.20   ->  exit 0
    better-sqlite3 resolved: 13.0.3
    dsh.profile.bundles: [..., "@memtensor/memos-local-plugin"]
    dsh --profile web --dump-config:
      # == @memtensor/memos-local-plugin
      - id: memos-local-memory
        name: '@memtensor/memos-local-plugin/dist/adapters/deepseek-harness/index.js'
    

    The same flow with ^12.10.0 fails with gyp: No Xcode or CLT version detected!.

    API compatibility

    I counted the better-sqlite3 surface actually used in the published 2.0.20 tarball:

    API call sites
    prepare 232
    exec 66
    close 64
    pragma 16
    iterate 16
    transaction 4

    backup, loadExtension, serialize, function, aggregate, table, raw, columns, safeIntegers, defaultSafeIntegers and explain are not used at all. Everything in the table above is stable core API; the only behaviour-firming change in the v13 line (table parameter validation, 13.0.2) is on an unused call.

    One install-flow caveat worth handling

    Seeding allowBuilds before the first add matters, and not only for tidiness. On this DSH build, a first add that fails at the pnpm build-script gate still writes the dependency into the profile's package.json but does not update dsh.profile.bundles. A later add then reports success (exit 0) without registering the bundle, leaving the plugin installed but never mounted. The documented add → approve-builds → add sequence can therefore land in that state, which your installer's --dump-config verification correctly catches as "DSH installed the dependency but did not activate the MemOS bundle."

    The one-command installer currently resolves builds only after the first failure. Pre-seeding the policy (as the manual section of the adapter README already shows) avoids the window. The underlying add behaviour does not look specific to this plugin, so it may be worth raising upstream separately.

  6. endxxxx commented on Oct 29, 2026

    @endxxxx
    Collaborator

    Fixed by #2519 and released in @memtensor/memos-local-plugin 2.0.21.

    The plugin now pins better-sqlite3 to 13.0.3, which ships Node-API prebuilt binaries, and updates the installation/build policies to avoid an unnecessary SQLite source rebuild. This addresses the Electron ABI mismatch and the failing node-gyp fallback described here.

    A clean Windows Desktop installation was verified against Electron 44: the host loaded prebuilds/win32-x64.node, SQLite operations succeeded, the Viewer returned HTTP 200, all six MemOS tools registered, and automatic capture/recall continued working after a full restart.

    Closing as fixed. Please upgrade to 2.0.21 and fully restart DSH.

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

Metadata

Metadata

Labels

area:pluginOpenClaw & Hermesstatus:needs-triageNeeds initial triage | 需要初步判断 & 问题复现types:bugSomething isn't working | 功能异常

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions