Skip to content

Bug: Bundled hooks broken on npm global install (Linux) — path resolution + missing handler files #11331

@matthewpoe

Description

@matthewpoe

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:

  1. Path resolution bug: resolveBundledHooksDir() cannot find dist/hooks/bundled/ (missing hooks/ in path join)
  2. 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

  1. Install OpenClaw globally on Linux: npm install -g openclaw@latest
  2. Configure hooks in openclaw.json with internal hooks enabled
  3. Start gateway: openclaw gateway
  4. Run: openclaw hooks list
  5. Expected: Lists session-memory, boot-md, command-logger, soul-evil
  6. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions