openclaw - 💡(How to fix) Fix [Bug]: Telegram plugin runtime-deps install fails with EACCES when OpenClaw is installed globally and gateway runs as non-root [3 comments, 4 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#69858Fetched 2026-04-22 07:47:20
View on GitHub
Comments
3
Participants
4
Timeline
8
Reactions
0
Author
Timeline (top)
commented ×3cross-referenced ×2labeled ×2closed ×1

After upgrading to 2026.4.20, the Telegram plugin fails to start because its runtime-deps installer attempts to stage files and run npm install inside the root-owned system path /usr/lib/node_modules/openclaw/dist/extensions/telegram/ while the gateway runs as a non-root user, so the plugin never gets its node_modules/.

Error Message

  • Either way, detect the permissions mismatch early and fail loudly with a clear error at update/gateway-install time, instead of silently leaving the plugin without deps.

Root Cause

After upgrading to 2026.4.20, the Telegram plugin fails to start because its runtime-deps installer attempts to stage files and run npm install inside the root-owned system path /usr/lib/node_modules/openclaw/dist/extensions/telegram/ while the gateway runs as a non-root user, so the plugin never gets its node_modules/.

Fix Action

Fix / Workaround

I do not have a verbatim gateway log line captured for the failure (Telegram was restored by manually creating a user-writable node_modules/ inside the plugin dir before logs could be collected). Happy to revert the workaround and capture a fresh log if the maintainers want one.


Affected: Any OpenClaw install where the package is installed globally (`npm install -g`) and the gateway runs as a non-root user — the standard "install once as root, run as user" pattern. All Telegram channel users on such installs.
Severity: High — Telegram channel does not start at all after the 2026.4.20 upgrade; all inbound/outbound Telegram traffic is blocked for the affected install until a manual filesystem workaround is applied.
Frequency: Always, on every gateway start under the affected install pattern, until the workaround is in place.
Consequence: Primary mobile channel is completely down — no incoming messages received, no replies sent, no heartbeats or alerts delivered.

Temporary workaround: manually created a user-writable `/usr/lib/node_modules/openclaw/dist/extensions/telegram/node_modules/` (owned by the gateway user) so the plugin's runtime-deps installer could succeed. After that, Telegram started normally on the same 4.20 build. This leaves a user-writable directory nested inside a root-owned install tree and will likely be overwritten or re-broken by the next `sudo openclaw update`; it should not be relied on.

Code Example

Environment / filesystem evidence on the affected host:

    $ openclaw --version
    OpenClaw 2026.4.20 (115f05d)

    $ stat -c '%U:%G %a %n' \
        /usr/lib/node_modules/openclaw \
        /usr/lib/node_modules/openclaw/dist \
        /usr/lib/node_modules/openclaw/dist/extensions \
        /usr/lib/node_modules/openclaw/dist/extensions/telegram
    root:root 755 /usr/lib/node_modules/openclaw
    root:root 755 /usr/lib/node_modules/openclaw/dist
    root:root 755 /usr/lib/node_modules/openclaw/dist/extensions
    root:root 755 /usr/lib/node_modules/openclaw/dist/extensions/telegram

    $ ls -la /usr/bin/openclaw
    lrwxrwxrwx 1 root root /usr/bin/openclaw -> ../lib/node_modules/openclaw/openclaw.mjs

Plugin manifest at /usr/lib/node_modules/openclaw/dist/extensions/telegram/package.json
declares runtime dependencies (@grammyjs/runner, @grammyjs/transformer-throttler,
@sinclair/typebox, grammy, undici) that require `npm install` to be resolvable.

Relevant code path in dist/install-package-dir-*.js:
  - computes installBaseRealPath from the plugin's parent directory
  - fs.mkdtemp(path.join(installBaseRealPath, ".openclaw-install-stage-"))
  - fs.cp(sourceDir, stageDir, { recursive: true })
  - runCommandWithTimeout(["npm","install","--omit=dev","--silent","--ignore-scripts"], { cwd: stageDir })

Every one of these writes requires write permission on
/usr/lib/node_modules/openclaw/dist/extensions/, which is root:root 755 on a
global (`npm install -g`) install — so a non-root gateway process cannot
execute them, and the plugin is left without its node_modules/.

I do not have a verbatim gateway log line captured for the failure (Telegram
was restored by manually creating a user-writable node_modules/ inside the
plugin dir before logs could be collected). Happy to revert the workaround
and capture a fresh log if the maintainers want one.
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

After upgrading to 2026.4.20, the Telegram plugin fails to start because its runtime-deps installer attempts to stage files and run npm install inside the root-owned system path /usr/lib/node_modules/openclaw/dist/extensions/telegram/ while the gateway runs as a non-root user, so the plugin never gets its node_modules/.

Steps to reproduce

Observed sequence on this host (Ubuntu 24.04 WSL2, OpenClaw originally installed via sudo npm i -g openclaw@beta, gateway run as a non-root user, Telegram channel configured):

  1. Starting version on disk: 2026.4.19-beta.2 (dc3df91), running cleanly including Telegram.
  2. Ran sudo openclaw update to move to 2026.4.20. After it completed, the Telegram channel did not come up.
  3. openclaw prompted to run openclaw gateway install --force, which I ran.
  4. openclaw --version still reported 2026.4.19-beta.2, so I re-ran sudo openclaw update.
  5. openclaw --version then reported 2026.4.20 (115f05d), but the Telegram plugin still would not start.
  6. Inspection showed /usr/lib/node_modules/openclaw/dist/extensions/telegram/ was root:root 755 with no node_modules/ under it, and the plugin could not install its runtime dependencies there as the non-root gateway user.

Expected replay on a clean host: install 2026.4.19-beta.2 via sudo npm i -g openclaw@beta (or any prior version that ran Telegram cleanly under this layout), configure a Telegram channel, then run sudo openclaw update to land on 2026.4.20 while the gateway runs as a non-root user. Telegram will fail to start on that 4.20 boot.

Expected behavior

2026.4.19-beta.2 (dc3df91) ran cleanly on this exact setup: global install under /usr/lib/node_modules/openclaw/ (root:root), gateway as a non-root user, Telegram channel configured. Telegram started on every gateway boot and polled normally. Running sudo openclaw update to move forward to 2026.4.20 was expected to land 4.20 on disk and have Telegram continue to start the same way.

Actual behavior

After the sudo openclaw update path landed 2026.4.20 on disk, the Telegram plugin did not start. The plugin directory /usr/lib/node_modules/openclaw/dist/extensions/telegram/ is root:root 755 and has no node_modules/. The runtime-deps installer in dist/install-package-dir-*.js — which stages into that directory via fs.mkdtemp(path.join(installBaseRealPath, ".openclaw-install-stage-")) and runs npm install --omit=dev --silent --ignore-scripts there — cannot write as the non-root gateway user, so the plugin is left without its declared dependencies (grammy, undici, @grammyjs/runner, @grammyjs/transformer-throttler, @sinclair/typebox). Telegram never initializes. After manually creating a user-writable node_modules/ inside the plugin dir, Telegram comes up normally on the same 4.20 build.

sudo openclaw update and openclaw gateway install --force both completed without surfacing this permissions problem; the failure was only visible downstream as "Telegram does not start."

OpenClaw version

2026.4.20 (115f05d)

Operating system

Ubuntu 24.04.4 LTS on WSL2 (kernel 6.6.87.2-microsoft-standard-WSL2, x86_64)

Install method

Global npm install. Originally installed via sudo npm i -g openclaw@beta (tracking the beta tag for the Telegram polling-stall fix). /usr/bin/openclaw is a root-owned symlink to /usr/lib/node_modules/openclaw/openclaw.mjs; the entire install tree under /usr/lib/node_modules/openclaw/ is root:root 755. Gateway runs as a regular (non-root) user account.

Model

N/A — this bug is independent of the model in use. The failure is in the Telegram plugin's filesystem/npm install step at gateway boot, before any model request is made. (For completeness, the default configured model on this install is anthropic/claude-sonnet-4-6.)

Provider / routing chain

N/A — this bug does not involve provider routing. The failure occurs in the Telegram channel plugin's runtime-deps installer at gateway startup, not in a model request path.

Additional provider/model setup details

N/A — not a model/provider issue.

Logs, screenshots, and evidence

Environment / filesystem evidence on the affected host:

    $ openclaw --version
    OpenClaw 2026.4.20 (115f05d)

    $ stat -c '%U:%G %a %n' \
        /usr/lib/node_modules/openclaw \
        /usr/lib/node_modules/openclaw/dist \
        /usr/lib/node_modules/openclaw/dist/extensions \
        /usr/lib/node_modules/openclaw/dist/extensions/telegram
    root:root 755 /usr/lib/node_modules/openclaw
    root:root 755 /usr/lib/node_modules/openclaw/dist
    root:root 755 /usr/lib/node_modules/openclaw/dist/extensions
    root:root 755 /usr/lib/node_modules/openclaw/dist/extensions/telegram

    $ ls -la /usr/bin/openclaw
    lrwxrwxrwx 1 root root /usr/bin/openclaw -> ../lib/node_modules/openclaw/openclaw.mjs

Plugin manifest at /usr/lib/node_modules/openclaw/dist/extensions/telegram/package.json
declares runtime dependencies (@grammyjs/runner, @grammyjs/transformer-throttler,
@sinclair/typebox, grammy, undici) that require `npm install` to be resolvable.

Relevant code path in dist/install-package-dir-*.js:
  - computes installBaseRealPath from the plugin's parent directory
  - fs.mkdtemp(path.join(installBaseRealPath, ".openclaw-install-stage-"))
  - fs.cp(sourceDir, stageDir, { recursive: true })
  - runCommandWithTimeout(["npm","install","--omit=dev","--silent","--ignore-scripts"], { cwd: stageDir })

Every one of these writes requires write permission on
/usr/lib/node_modules/openclaw/dist/extensions/, which is root:root 755 on a
global (`npm install -g`) install — so a non-root gateway process cannot
execute them, and the plugin is left without its node_modules/.

I do not have a verbatim gateway log line captured for the failure (Telegram
was restored by manually creating a user-writable node_modules/ inside the
plugin dir before logs could be collected). Happy to revert the workaround
and capture a fresh log if the maintainers want one.

Impact and severity

Affected: Any OpenClaw install where the package is installed globally (npm install -g) and the gateway runs as a non-root user — the standard "install once as root, run as user" pattern. All Telegram channel users on such installs. Severity: High — Telegram channel does not start at all after the 2026.4.20 upgrade; all inbound/outbound Telegram traffic is blocked for the affected install until a manual filesystem workaround is applied. Frequency: Always, on every gateway start under the affected install pattern, until the workaround is in place. Consequence: Primary mobile channel is completely down — no incoming messages received, no replies sent, no heartbeats or alerts delivered.

Additional information

Regression introduced in 2026.4.20, reached via sudo openclaw update from 2026.4.19-beta.2.

  • Last known good version on this host: 2026.4.19-beta.2 (dc3df91), installed via sudo npm i -g openclaw@beta and running cleanly for multiple days including Telegram.

  • First known bad version on this host: 2026.4.20 (115f05d).

  • Upgrade path that produced the bad state: sudo openclaw updateopenclaw gateway install --force (suggested by openclaw itself when Telegram didn't come up) → sudo openclaw update again to actually land 4.20.

  • At no point during those commands did anything surface that the Telegram plugin had been left without its runtime dependencies; the failure was silent from the update tooling's point of view.

Suggested fixes:

  • Bundle Telegram's runtime deps into the release tarball so no install step is needed at gateway start, matching other extensions that don't require runtime npm install.
  • Or install runtime deps into a user-writable location (e.g. ~/.openclaw/runtime-deps/telegram/) and have the plugin loader add that path to its module resolution. This aligns with the common "install once as root, run as user" deployment pattern.
  • Either way, detect the permissions mismatch early and fail loudly with a clear error at update/gateway-install time, instead of silently leaving the plugin without deps.

Temporary workaround: manually created a user-writable /usr/lib/node_modules/openclaw/dist/extensions/telegram/node_modules/ (owned by the gateway user) so the plugin's runtime-deps installer could succeed. After that, Telegram started normally on the same 4.20 build. This leaves a user-writable directory nested inside a root-owned install tree and will likely be overwritten or re-broken by the next sudo openclaw update; it should not be relied on.

Related but separate: there is an existing open issue about the Telegram transport rebuild silently failing to resume polling after a stall. That issue is still valid — this permissions bug just masked it in 4.20 by preventing Telegram from initializing in the first place. Please keep the two issues distinct.

Again, this was prepared by Opus 4.7 based on information from Claude Code using Sonnet and the logs of the events.

Reporting so others can avoid this. Thank you.

extent analysis

TL;DR

The Telegram plugin fails to start after upgrading to OpenClaw 2026.4.20 due to a permissions issue, where the plugin's runtime dependencies cannot be installed in the root-owned system path.

Guidance

  • The issue is caused by the npm install command being run as a non-root user in a root-owned directory, which lacks write permissions.
  • To verify the issue, check the permissions of the /usr/lib/node_modules/openclaw/dist/extensions/telegram/ directory and the presence of a node_modules/ directory within it.
  • A temporary workaround is to manually create a user-writable node_modules/ directory inside the plugin directory, but this is not a reliable solution.
  • A more permanent fix would be to bundle the Telegram plugin's runtime dependencies into the release tarball or install them in a user-writable location.

Example

No code snippet is provided as the issue is related to file system permissions and not a specific code error.

Notes

The issue is specific to OpenClaw 2026.4.20 and may not affect other versions. The problem is also dependent on the installation method (global install via npm install -g) and the user running the gateway (non-root user).

Recommendation

Apply a workaround by installing runtime dependencies in a user-writable location, such as ~/.openclaw/runtime-deps/telegram/, to align with the common "install once as root, run as user" deployment pattern. This approach allows the plugin to install its dependencies without requiring root permissions.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

2026.4.19-beta.2 (dc3df91) ran cleanly on this exact setup: global install under /usr/lib/node_modules/openclaw/ (root:root), gateway as a non-root user, Telegram channel configured. Telegram started on every gateway boot and polled normally. Running sudo openclaw update to move forward to 2026.4.20 was expected to land 4.20 on disk and have Telegram continue to start the same way.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING