#17151: fix: add npm link to fix CLI permission denied (exit 127)
docker
stale
size: XS
Cluster:
Docker and Deployment Improvements
## Summary
Describe the problem and fix in 2–5 bullets:
* Problem: The openclaw CLI command fails with sh: 1: openclaw: Permission denied (exit code 127) when executed by the running agent process (as the node user) inside the container.
* Why it matters: The agent cannot perform self-management tasks (like openclaw gateway status, openclaw --version, or restarts) because it lacks execution permissions or a proper symlink in the non-interactive path.
* What changed: Added RUN npm link to the Dockerfile.
* What did NOT change (scope boundary): No changes to runtime logic or other build steps.
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [x] Chore/infra
## Scope (select all touched areas)
- [ ] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [ ] Integrations
- [ ] API / contracts
- [ ] UI / DX
- [x] CI/CD / infra
## Linked Issue/PR
- Closes #
- Related #
## User-visible / Behavior Changes
The agent running inside the Docker container can now successfully execute openclaw CLI commands for self-management.
## Security Impact (required)
- New permissions/capabilities? (No)
- Secrets/tokens handling changed? (No)
- New/changed network calls? (No)
- Command/tool execution surface changed? (Yes) - Restores the intended ability for the node user to execute the openclaw binary.
- Data access scope changed? (No)
- If any Yes, explain risk + mitigation:
## Repro + Verification
### Environment
* OS: Docker (Linux)
* Runtime/container: node:22-bookworm
### Steps
1. Start the container normally.
1. Ask the agent to check its version (or execute openclaw --version via the agent's exec tool).
1. Observe error: sh: 1: openclaw: Permission denied.
(Note: `docker compose run --rm openclaw-cli --version` might work depending on user context, but the internal agent process fails.)
### Expected
- Agent successfully reports the version.
### Actual
- Agent reports `Permission denied (exit code 127)`.
## Evidence
Attach at least one:
- [x] Failing test/log before + passing after
- [ ] Trace/log snippets
- [ ] Screenshot/recording
- [ ] Perf numbers (if relevant)
### before fix
```
openclaw-gateway-1 | 2026-02-15T12:12:03.612+00:00 [tools] exec failed: sh: 1: openclaw: Permission denied
openclaw-gateway-1 | Command exited with code 127
```
### after fix
Agent successfully executes openclaw --version.
## Human Verification (required)
What you personally verified (not just CI), and how:
- Verified scenarios: Built the Docker image locally with `RUN npm link`, ran the container, and confirmed the agent could execute `openclaw --version`.
- Edge cases checked: None specific.
- What you did **not** verify:
## Compatibility / Migration
- Backward compatible? (`Yes`)
- Config/env changes? (`No`)
- Migration needed? (`No`)
- If yes, exact upgrade steps:
## Failure Recovery (if this breaks)
- How to disable/revert this change quickly: Revert Dockerfile change.
- Files/config to restore: `Dockerfile`
- Known bad symptoms reviewers should watch for: Build failures
## Risks and Mitigations
List only real risks for this PR. Add/remove entries as needed. If none, write `None`.
- Risk: None (standard npm functionality).
- Mitigation: N/A
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds `RUN npm link` to the Dockerfile to make the `openclaw` CLI command available globally within the container. This resolves the "command not found" (exit 127) error when the agent process tries to execute `openclaw` commands like `openclaw --version` or `openclaw gateway status` for self-management tasks.
- Simple one-line addition that creates a global symlink for the `openclaw` binary
- Change placed appropriately after build steps but before switching to the node user
- Follows standard npm packaging practices for CLI tools
<h3>Confidence Score: 5/5</h3>
- Safe to merge - standard npm CLI setup with no risks
- Single line addition using standard npm functionality (`npm link`) to expose the CLI binary. No logic changes, no security implications, and properly placed in the Dockerfile build sequence. The fix is straightforward and addresses a legitimate missing step in the Docker build process.
- No files require special attention
<sub>Last reviewed commit: 29329ae</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#17506: Fix Entrypoint in docker-compose
by NeilSCGH · 2026-02-15
82.2%
#21934: fix #21914 - Add the most obvious option to the error message
by vivganes · 2026-02-20
80.4%
#22491: Use multi-stage docker build to reduce image size from 4.72GB -> 2....
by mm-zacharydavison · 2026-02-21
79.6%
#6631: fix: configure npm global prefix for non-root user in Docker
by tjetzinger · 2026-02-01
79.5%
#23798: docs: add Docker pairing cross-reference to Control UI page
by dglewis · 2026-02-22
79.3%
#12504: fix: allow docker cli container to connect to gateway
by bvanderdrift · 2026-02-09
78.9%
#23313: feat(docker): add optional build-arg OPENCLAW_INSTALL_DOCKER_CLI to...
by zhuxuwei88-bot · 2026-02-22
78.9%
#6698: feat: Add CLI wrapper for Docker integration and update documentation
by barshopen · 2026-02-01
78.8%
#9190: feat(docker): Add autonomous container self-restart and runtime pac...
by alexdredmon · 2026-02-05
78.7%
#22662: fix: use OPENCLAW_GATEWAY_TOKEN env var in onboard QuickStart
by aiworks451 · 2026-02-21
78.5%