Skip to content

[Bug]: npm install -g openclaw fails in environments without GitHub SSH keys #12841

@nachoaIvarez

Description

@nachoaIvarez

Summary

npm install -g openclaw@latest fails on first run in any environment without GitHub SSH keys configured. The root cause is @whiskeysockets/baileys@7.0.0-rc.9 declaring libsignal as a raw git URL (git+https://github.com/whiskeysockets/libsignal-node) instead of using the npm-published @whiskeysockets/libsignal-node@2.0.1. npm rewrites this to an SSH git operation that requires GitHub auth.

This breaks Docker containers, CI runners, fresh VMs, and cloud dev environments out of the box.

Retrying after the failure hits a secondary issue: npm leaves a stale temp directory behind (.openclaw-ScBINLhf), causing an ENOTEMPTY error that requires manual cleanup before the install can succeed.

Dependency chain:

openclaw@2026.2.9
  └── @whiskeysockets/baileys@7.0.0-rc.9
        └── libsignal: "git+https://github.com/whiskeysockets/libsignal-node"

Steps to reproduce

  1. Spin up any clean environment without GitHub SSH keys (Docker container, fresh VM, CI runner)
  2. Run npm install -g openclaw@latest
  3. Install fails with Permission denied (publickey)
  4. Retry npm install -g openclaw@latest
  5. Retry fails with ENOTEMPTY because npm didn't clean up after step 3

Expected behavior

npm install -g openclaw should succeed without requiring GitHub SSH keys. All transitive dependencies should resolve from the npm registry.

Actual behavior

First attempt fails with a git SSH auth error:

npm error code 128
npm error An unknown git error occurred
npm error command git --no-replace-objects ls-remote ssh://git@github.com/whiskeysockets/libsignal-node.git
npm error git@github.com: Permission denied (publickey).
npm error fatal: Could not read from remote repository.

Second attempt fails because npm left a partial install behind:

npm error ENOTEMPTY: directory not empty, rename '/path/to/node_modules/openclaw' -> '/path/to/node_modules/.openclaw-ScBINLhf'

After manually removing the stale temp dir (rm -rf .../node_modules/.openclaw-ScBINLhf) and retrying, the install eventually succeeds — npm appears to fall back to the registry-published version on subsequent attempts.

Environment

  • Clawdbot version: 2026.2.9
  • OS: Ubuntu (Docker container, no GitHub SSH keys)
  • Install method: npm install -g openclaw@latest
  • Node.js: v22.22.0
  • npm: 10.9.4

Logs or screenshots

Full npm debug log from the first failure:

verbose stack Error: An unknown git error occurred
verbose stack     at makeError (/mise/installs/node/22.22.0/lib/node_modules/npm/node_modules/@npmcli/git/lib/make-error.js:28:13)
verbose stack     at /mise/installs/node/22.22.0/lib/node_modules/npm/node_modules/@npmcli/git/lib/spawn.js:37:26
verbose stack     at async module.exports (/mise/installs/node/22.22.0/lib/node_modules/npm/node_modules/@npmcli/git/lib/revs.js:18:22)
verbose stack     at async /mise/installs/node/22.22.0/lib/node_modules/npm/node_modules/pacote/lib/git.js:258:19
verbose stack     at async withTempDir (/mise/installs/node/22.22.0/lib/node_modules/npm/node_modules/@npmcli/fs/lib/with-temp-dir.js:21:14)
verbose stack     at async #fetchManifest (/mise/installs/node/22.22.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js:1202:20)
verbose stack     at async #nodeFromEdge (/mise/installs/node/22.22.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js:1040:19)
verbose stack     at async #buildDepStep (/mise/installs/node/22.22.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js:904:11)
verbose stack     at async Arborist.buildIdealTree (/mise/installs/node/22.22.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js:181:7)
error code 128
error command git --no-replace-objects ls-remote ssh://git@github.com/whiskeysockets/libsignal-node.git
error git@github.com: Permission denied (publickey).
error fatal: Could not read from remote repository.

Suggested fixes:

  1. Upstream (preferred): Get @whiskeysockets/baileys to use @whiskeysockets/libsignal-node@^2.0.1 from npm instead of the git URL.
  2. Override workaround: Add to package.json:
    "overrides": {
      "@whiskeysockets/baileys": {
        "libsignal": "npm:@whiskeysockets/libsignal-node@^2.0.1"
      }
    }
  3. Make WhatsApp optional: Move @whiskeysockets/baileys to optionalDependencies so the base install doesn't blow up for users who don't need WhatsApp.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions