Skip to content

fix(plugins): repair missing openclaw peer links on update#77544

Merged
steipete merged 2 commits into
openclaw:mainfrom
ProspectOre:codex/plugin-sdk-resolution
May 5, 2026
Merged

fix(plugins): repair missing openclaw peer links on update#77544
steipete merged 2 commits into
openclaw:mainfrom
ProspectOre:codex/plugin-sdk-resolution

Conversation

@ProspectOre

Copy link
Copy Markdown
Contributor

Summary

Repair npm-installed plugins that declare peerDependencies.openclaw when their plugin-local node_modules/openclaw link is missing or dangling.

The npm update path already skips reinstalling unchanged artifacts when version and integrity match. That skip is correct only if the installed plugin runtime graph is complete. This change bypasses the skip for packages that declare the OpenClaw host peer but cannot resolve node_modules/openclaw, allowing the existing installer/linker path to repair the install.

Root Cause

@openclaw/codex imports openclaw/plugin-sdk/* through its published bundle and declares openclaw as a peer dependency. Fresh OpenClaw-managed installs already create the plugin-local peer link. Existing installs missing that link can remain broken across OTA because updateNpmInstalledPlugins() returns unchanged before invoking the installer when the package version and integrity still match.

That leaves the plugin installed but unable to import openclaw/plugin-sdk/*, producing ERR_MODULE_NOT_FOUND even though the installed package version is current.

Validation

  • npx --yes pnpm@10.33.2 node scripts/test-projects.mjs src/plugins/update.test.ts (64 passed)
  • npx --yes pnpm@10.33.2 tsgo:core
  • npx --yes pnpm@10.33.2 exec oxlint src/infra/package-update-utils.ts src/plugins/update.ts src/plugins/update.test.ts
  • npx --yes pnpm@10.33.2 exec oxfmt --check src/infra/package-update-utils.ts src/plugins/update.ts src/plugins/update.test.ts
  • Patched source repro: raw @openclaw/codex@2026.5.3 install without @openclaw/codex/node_modules/openclaw; updater repaired the link and reported the plugin unchanged at 2026.5.3.

@ProspectOre ProspectOre marked this pull request as ready for review May 4, 2026 21:38
@clawsweeper

clawsweeper Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

Summary
The PR adds an installed-package manifest helper, bypasses the unchanged npm-update fast path when an OpenClaw peer link is missing, adds focused update regression tests, and records the fix in the changelog.

Reproducibility: yes. Source inspection shows current main can return unchanged for a matching npm install before installPluginFromNpmSpec reaches installPluginFromInstalledPackageDir and linkOpenClawPeerDependencies; I did not mutate a local install for a live reproduction because this sweep was read-only.

Next step before merge
No repair job is needed because the prior changelog finding has been fixed and the remaining action is ordinary maintainer review or merge of the contributor PR.

Security
Cleared: The diff only adds local package-manifest and peer-link checks before reusing the existing npm installer/linker flow, with no new dependency source, workflow permission, secret handling, or package execution surface.

Review details

Best possible solution:

Merge this PR after normal maintainer review while preserving the changelog entry and regression coverage around the unchanged npm-plugin update path.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection shows current main can return unchanged for a matching npm install before installPluginFromNpmSpec reaches installPluginFromInstalledPackageDir and linkOpenClawPeerDependencies; I did not mutate a local install for a live reproduction because this sweep was read-only.

Is this the best way to solve the issue?

Yes. Reusing the existing installer/linker path only when an installed package declares an OpenClaw host peer and lacks a usable local link is the narrow maintainable fix, and the force-pushed changelog entry resolves the earlier process blocker.

What I checked:

  • Current main unchanged skip: On current main, updateNpmInstalledPlugins can return an unchanged outcome for npm installs when version, resolution, integrity, and shasum match, before the npm installer path is invoked. (src/plugins/update.ts:980, 43b5df729593)
  • Installer-owned peer repair: The existing install path calls scanAndLinkInstalledPackage, which invokes linkOpenClawPeerDependencies for packages whose peerDependencies include openclaw. (src/plugins/install.ts:929, 43b5df729593)
  • Peer-link implementation: linkOpenClawPeerDependencies creates node_modules/openclaw as a symlink to the host OpenClaw package root when the plugin declares openclaw as a peer dependency. (src/plugins/plugin-peer-link.ts:15, 43b5df729593)
  • PR functional change: The PR adds installedPackageNeedsOpenClawPeerLinkRepair and gates the unchanged npm skip on that helper, so missing or dangling plugin-local OpenClaw peer links fall through to the existing installer/linker path. (src/plugins/update.ts:990, 0f051140fe71)
  • PR regression coverage: The PR adds update-path coverage for repairing a missing OpenClaw peer link before skipping unchanged npm plugins and for preserving the fast path when the link is present. (src/plugins/update.test.ts:720, 0f051140fe71)
  • Changelog blocker resolved: The current PR diff adds a user-facing CHANGELOG.md Fixes entry for the plugin-local openclaw peer-link update repair, addressing the prior ClawSweeper P3 finding. (CHANGELOG.md:53, 0f051140fe71)

Likely related people:

  • vincentkoc: Available history shows Vincent Koc introduced the current package update helper, install path, peer-link helper, and recently maintained plugin update failure handling. (role: introduced behavior and adjacent maintainer; confidence: high; commits: daefb5e3412f, 7c0f5463a564; files: src/infra/package-update-utils.ts, src/plugins/install.ts, src/plugins/plugin-peer-link.ts)
  • steipete: Peter Steinberger recently changed the same plugin npm update path for beta fallback behavior, making him a useful reviewer for update-policy implications. (role: recent maintainer; confidence: medium; commits: 4820b701a597; files: src/plugins/update.ts, src/plugins/update.test.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against 43b5df729593.

@ProspectOre ProspectOre force-pushed the codex/plugin-sdk-resolution branch from 0bddca5 to 0f05114 Compare May 4, 2026 21:55

gmann14 commented May 5, 2026

Copy link
Copy Markdown

Adding a real-world repro/validation point from a live macOS install, since this matches the failure mode I hit today.

Environment:

  • OpenClaw 2026.5.3-1 (2eae30e)
  • Managed npm root: ~/.openclaw/npm
  • Installed plugin package: @openclaw/codex@2026.5.3
  • Failure importer: ~/.openclaw/npm/node_modules/@openclaw/codex/dist/client-chGfNrq5.js

Symptoms before repair:

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'openclaw' imported from ~/.openclaw/npm/node_modules/@openclaw/codex/dist/client-chGfNrq5.js
Embedded agent failed before reply: Cannot find package 'openclaw' imported from ~/.openclaw/npm/node_modules/@openclaw/codex/dist/client-chGfNrq5.js

This affected interactive, heartbeat, Telegram topic, and cron lanes. The gateway stayed up, but Codex-backed turns failed before reply, which made the system feel like it was hanging/stopped responding.

Local state after manual workaround:

~/.openclaw/npm/node_modules/openclaw                      present
~/.openclaw/npm/node_modules/@openclaw/codex/node_modules/openclaw  missing

The workaround was to install openclaw@2026.5.3 into ~/.openclaw/npm, then restart the gateway. After that, the SDK import resolved and a smoke test passed:

Reply: CODEX_PEER_FIX_OK
agentHarnessId: codex
provider: openai
model: gpt-5.5
fallbackUsed: false

So the important upstream behavior is exactly what this PR is targeting: an unchanged/current managed npm plugin should not be considered healthy when its openclaw peer import cannot resolve. Repairing through the existing installer/linker path is better than requiring users to manually add openclaw to the managed npm root.

@steipete steipete force-pushed the codex/plugin-sdk-resolution branch from 0f05114 to cdf2018 Compare May 5, 2026 04:00
@steipete steipete merged commit 712aa96 into openclaw:main May 5, 2026
104 of 107 checks passed
@steipete

steipete commented May 5, 2026

Copy link
Copy Markdown
Contributor

Landed via rebase onto main.

  • Rebased PR head: cdf2018
  • Landed commits: 2e8761c / 712aa96
  • Verification:
    • pnpm test src/plugins/update.test.ts -- -t "repairs missing openclaw peer links before skipping unchanged npm plugins|skips unchanged npm plugins when the openclaw peer link already resolves"
    • pnpm exec oxfmt --check --threads=1 src/infra/package-update-utils.ts src/plugins/update.ts src/plugins/update.test.ts CHANGELOG.md
    • Crabbox pnpm check:changed: tbx_01kqv4jpqy5msx31ae94qbqpxk, exit 0

Thanks @ProspectOre!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants