openclaw - ✅(Solved) Fix Web UI "Update" button corrupts installation — missing core files, gateway unable to start [1 pull requests, 1 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#62984Fetched 2026-04-09 07:59:49
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Author
Participants
Assignees
Timeline (top)
assigned ×1cross-referenced ×1

Clicking the "Update" button in the OpenClaw Web UI results in a corrupted installation. After the update process runs, most core files are deleted and the gateway cannot start.

Error Message

Error: Cannot find module '/opt/homebrew/lib/node_modules/openclaw/dist/index.js' at Function._resolveFilename (node:internal/modules/cjs/loader:1405:15) ... code: 'MODULE_NOT_FOUND', requireStack: []

Root Cause

The self-update mechanism seems to perform a non-atomic replacement: it removes the old installation files first, then writes the new ones. If the write phase fails or is interrupted for any reason, the installation is left in an unrecoverable "half-deleted" state.

Fix Action

Workaround

Manually reinstall via npm:

npm install -g openclaw

The ~/.openclaw config directory is unaffected, so no data is lost.

PR fix notes

PR #63065: release: mirror bundled channel deps at root

Description (problem / solution / changelog)

Summary

  • Problem: bundled Slack, Telegram, Discord, and Feishu runtime packages were still imported from root dist/*.js chunks, but they were not mirrored in the root npm manifest.
  • Why it matters: fresh installs and upgrades could ship a broken package that depended on best-effort postinstall recovery, which matched the missing-module failures in #62749, #62952, #62994, and #63043.
  • What changed: mirrored the root-resolved bundled channel deps into the root manifest, declared them through openclaw.releaseChecks.rootDependencyMirrorAllowlist, and hardened the npm postpublish verifier to check mirrored deps plus run the installed openclaw --version binary.
  • What did NOT change (scope boundary): I did not change bundled plugin staging behavior for extension-local node_modules, nor the self-update flow from #62984.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #62749
  • Related #62952
  • Related #62994
  • Related #63043
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: bundled channel/plugin code was code-split into root dist/*.js chunks that resolve packages from the package root, but the root npm manifest did not mirror those runtime dependencies.
  • Missing detection / guardrail: the existing release checks only validated a small set of mirrored deps and the postpublish verify path did not exercise the installed openclaw binary or validate mirrored root deps from bundled extension manifests.
  • Contributing context (if known): the package still relied on best-effort postinstall repair, so environments where that recovery path failed surfaced user-visible missing-module crashes.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: test/openclaw-npm-postpublish-verify.test.ts
  • Scenario the test should lock in: bundled extensions that declare root-mirrored runtime deps must be satisfied by the installed package root manifest, and published install verification must reject drift.
  • Why this is the smallest reliable guardrail: it validates the packaged manifest contract directly without needing a full publish cycle.
  • Existing test that already covers this (if any): test/release-check.test.ts already covers the generic root-mirror allowlist rules.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • npm installs now carry the bundled channel runtime deps that root dist/*.js chunks actually import, instead of relying on postinstall recovery to backfill them.
  • Postpublish verification now fails if the installed package loses those mirrored deps or if the installed openclaw binary cannot report its version.

Diagram (if applicable)

Before:
[npm install openclaw] -> [root dist chunk imports bundled channel package] -> [package missing at root] -> [runtime crash unless postinstall recovers]

After:
[npm install openclaw] -> [root manifest already mirrors root-resolved bundled channel deps] -> [runtime import resolves] -> [binary smoke + postpublish verify catch drift]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS 15.7.1 host
  • Runtime/container: Node 25 host tooling, repo release scripts
  • Model/provider: N/A
  • Integration/channel (if any): Slack / Telegram / Discord / Feishu packaging surfaces
  • Relevant config (redacted): N/A

Steps

  1. Build the repo release artifact surfaces.
  2. Run the packaging checks and postpublish verifier unit tests.
  3. Confirm root dist/*.js imports are mirrored in the root manifest through extension allowlists.

Expected

  • Release checks pass.
  • The packaged manifest explicitly mirrors root-resolved bundled channel deps.
  • Postpublish verification would fail if those mirrored deps drift again.

Actual

  • pnpm release:check passed after pnpm build and pnpm ui:build.
  • Targeted verifier tests passed.
  • The four affected bundled extensions now declare the mirrored root deps they require.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: pnpm test test/openclaw-npm-postpublish-verify.test.ts, pnpm test test/release-check.test.ts, pnpm build, pnpm ui:build, pnpm release:check
  • Edge cases checked: optional root mirror for @discordjs/opus; installed-package manifest drift detection for mirrored bundled deps
  • What you did not verify: I did not fully re-test the separate Web UI self-update corruption path from #62984, and the local tarball global-install smoke was slower than the targeted release checks so I relied on the hardened verifier + release gate rather than waiting for that extra run.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: root dependency surface grows for the mirrored bundled channel packages.
    • Mitigation: each added mirror is now declared by the owning extension through rootDependencyMirrorAllowlist, checked by release-check, and validated again in postpublish verification.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • extensions/discord/package.json (modified, +8/-0)
  • extensions/feishu/package.json (modified, +5/-0)
  • extensions/slack/package.json (modified, +7/-0)
  • extensions/telegram/package.json (modified, +7/-0)
  • package.json (modified, +10/-0)
  • pnpm-lock.yaml (modified, +31/-1)
  • scripts/openclaw-npm-postpublish-verify.ts (modified, +180/-2)
  • src/plugins/contracts/package-manifest.contract.test.ts (modified, +17/-6)
  • test/helpers/plugins/package-manifest-contract.ts (modified, +35/-5)
  • test/openclaw-npm-postpublish-verify.test.ts (modified, +187/-0)

Code Example

/opt/homebrew/lib/node_modules/openclaw/
├── dist/
│   └── extensions/          # only empty subdirectories (amazon-bedrock, discord, diffs, etc.)
└── node_modules/
    └── @img, @lydell, @mariozechner, @napi-rs, @types   # all empty

---

Error: Cannot find module '/opt/homebrew/lib/node_modules/openclaw/dist/index.js'
    at Function._resolveFilename (node:internal/modules/cjs/loader:1405:15)
    ...
  code: 'MODULE_NOT_FOUND',
  requireStack: []

---

npm install -g openclaw
RAW_BUFFERClick to expand / collapse

Description

Clicking the "Update" button in the OpenClaw Web UI results in a corrupted installation. After the update process runs, most core files are deleted and the gateway cannot start.

Steps to Reproduce

  1. Run OpenClaw gateway normally (openclaw gateway)
  2. Open the Web UI (canvas)
  3. Click the "Update" button
  4. Gateway crashes and openclaw CLI becomes unavailable

Expected Behavior

OpenClaw should update to the new version seamlessly, or roll back to the previous version if the update fails.

Actual Behavior

The update process appears to delete the old installation before the new version is fully written. The result is a broken installation:

Missing files

  • package.json — completely absent
  • dist/index.js — the main entry point, absent
  • bin/ directory — absent
  • /opt/homebrew/bin/openclaw symlink — removed

Remaining files

Only partial directory skeletons remain:

/opt/homebrew/lib/node_modules/openclaw/
├── dist/
│   └── extensions/          # only empty subdirectories (amazon-bedrock, discord, diffs, etc.)
└── node_modules/
    └── @img, @lydell, @mariozechner, @napi-rs, @types   # all empty

Error log

Gateway repeatedly crashes with:

Error: Cannot find module '/opt/homebrew/lib/node_modules/openclaw/dist/index.js'
    at Function._resolveFilename (node:internal/modules/cjs/loader:1405:15)
    ...
  code: 'MODULE_NOT_FOUND',
  requireStack: []

Workaround

Manually reinstall via npm:

npm install -g openclaw

The ~/.openclaw config directory is unaffected, so no data is lost.

Root Cause Analysis

The self-update mechanism seems to perform a non-atomic replacement: it removes the old installation files first, then writes the new ones. If the write phase fails or is interrupted for any reason, the installation is left in an unrecoverable "half-deleted" state.

Suggested Fix

Consider one of the following approaches:

  1. Atomic swap: Download and extract the new version to a temporary directory, verify integrity, then rename/swap the directories in a single operation.
  2. Rollback support: Keep a backup of the old installation until the new version is verified to be working, and restore it on failure.
  3. Use npm install -g: Delegate the update to npm itself, which already handles atomic replacement.

Environment

  • OpenClaw version: updating to 2026.4.8 (version before update unknown)
  • Install method: npm install -g openclaw
  • Install path: /opt/homebrew/lib/node_modules/openclaw/
  • OS: macOS 14.5 (Sonoma), Apple Silicon
  • Node.js: v23.11.0
  • npm: 10.9.2

extent analysis

TL;DR

Implement an atomic replacement or rollback mechanism in the self-update process to prevent partial installation deletions.

Guidance

  • Verify the integrity of the new version before removing the old installation files to prevent data loss.
  • Consider using a temporary directory to download and extract the new version, then rename or swap the directories in a single operation.
  • Implement rollback support to restore the old installation in case the new version fails to install or function correctly.
  • As a temporary workaround, use npm install -g openclaw to update the installation, which handles atomic replacement.

Example

No code snippet is provided as the issue does not imply a specific code change, but rather a change in the update mechanism.

Notes

The suggested fix assumes that the self-update mechanism can be modified to handle atomic replacement or rollback. If this is not possible, delegating the update to npm install -g may be a viable alternative.

Recommendation

Apply a workaround by using npm install -g openclaw for updates, as it already handles atomic replacement and can prevent partial installation deletions. This approach is recommended because it leverages an existing, reliable update mechanism.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING