-
-
Notifications
You must be signed in to change notification settings - Fork 55.2k
Description
Summary
Bundled hooks (session-memory, boot-md, command-logger, soul-evil) are completely non-functional when OpenClaw is installed via npm install -g openclaw on Linux. Two separate bugs prevent them from loading:
- Path resolution bug: resolveBundledHooksDir() cannot find dist/hooks/bundled/ (missing hooks/ in path join)
- Build/packaging bug: Even when the directory is found, only HOOK.md files exist — no handler.ts or handler.js files are emitted by the build
This is the same class of path resolution bug as #8905 (Chrome extension bundled path), which was fixed in #8914 for the extension but not for hooks.
Affected versions: 2026.2.4 through 2026.2.6-3 (at minimum)
Install method: npm install -g openclaw (standard global install on Linux)
Platform: Ubuntu 24.04 (DigitalOcean droplet), Node v22.22.0
Evidence That Hooks Work Elsewhere
Other users gateway logs show hooks loading successfully (e.g., #3089, #3815):
Registered hook: boot-md -> gateway:startup
Registered hook: command-logger -> command
Registered hook: session-memory -> command:new
[hooks] loaded 3 internal hook handlers
These appear to be macOS/homebrew or from-source installs where either handler.ts is loaded directly via tsx runtime, or the path resolution works differently.
Reproduction
- Install OpenClaw globally on Linux: npm install -g openclaw@latest
- Configure hooks in openclaw.json with internal hooks enabled
- Start gateway: openclaw gateway
- Run: openclaw hooks list
- Expected: Lists session-memory, boot-md, command-logger, soul-evil
- Actual: No hooks found.
Bug 1: Path Resolution
resolveBundledHooksDir() in src/hooks/bundled-dir.ts checks three candidate paths. On npm global install, import.meta.url resolves to a chunk in dist/, so moduleDir = /usr/lib/node_modules/openclaw/dist/. The code looks for dist/bundled but the actual path is dist/hooks/bundled.
Proposed fix:
- const distBundled = path.join(moduleDir, "bundled");
+ const distBundled = path.join(moduleDir, "hooks", "bundled");
Workaround: export OPENCLAW_BUNDLED_HOOKS_DIR=/usr/lib/node_modules/openclaw/dist/hooks/bundled
This workaround confirms the fix — setting the env var makes the gateway find all four hook directories. But they still fail to load due to Bug 2.
Bug 2: Missing Handler Files in npm Package
After applying the env var workaround, gateway logs show:
[hooks] Hook "session-memory" has HOOK.md but no handler file
[hooks] Hook "boot-md" has HOOK.md but no handler file
[hooks] Hook "command-logger" has HOOK.md but no handler file
[hooks] Hook "soul-evil" has HOOK.md but no handler file
The source tree has handler.ts files alongside HOOK.md, but the npm-published dist only contains HOOK.md. The build step that copies HOOK.md to dist/hooks/bundled/ does not compile or copy the handler.ts files alongside them. In dev mode (tsx), handler.ts is loaded directly from source. In npm global installs, the compiled JS does not exist.
Impact
All bundled hooks are non-functional on npm global installs:
- session-memory: Memory files not created on /new command
- command-logger: No command audit logging
- boot-md: BOOT.md not executed on gateway startup
- soul-evil: Soul swap feature inoperable
Environment
OpenClaw: 2026.2.6-3 (85ed6c7)
Node: v22.22.0
OS: Ubuntu 24.04 (DigitalOcean)
Install: npm install -g openclaw@latest
Related Issues
- [Bug]: openclaw browser extension install fails: bundled extension path resolves outside package #8905 — Same class of path resolution bug (Chrome extension)
- Fix chrome extension bundled path resolution #8914 — PR that fixed Chrome extension path but missed hooks