openclaw - 💡(How to fix) Fix [Bug]: Diffs plugin fails to load from nested openclaw peer dep in opik-openclaw extension [2 comments, 2 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#55436Fetched 2026-04-08 01:39:31
View on GitHub
Comments
2
Participants
2
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
commented ×2closed ×1locked ×1

Error Message

[plugins] diffs failed to load from /Users/<user>/.openclaw/extensions/opik-openclaw/node_modules/openclaw/dist/extensions/diffs/index.js: Error: Cannot find module '@pierre/diffs'

Root Cause

  1. opik-openclaw declares openclaw as a peerDependency (>=2026.3.2)
  2. npm install resolves this by placing a full 209MB copy of openclaw at ~/.openclaw/extensions/opik-openclaw/node_modules/openclaw/
  3. That nested copy includes dist/extensions/diffs/index.js (the diffs extension entry point)
  4. But @pierre/diffs is not installed in the nested copy's dependency tree — it's only installed in the real openclaw at /opt/homebrew/lib/node_modules/openclaw/dist/extensions/diffs/node_modules/
  5. The gateway plugin scanner walks into the nested copy, finds the diffs entry point, and tries to load it → Cannot find module @pierre/diffs

The real diffs extension at the stock path loads fine. The error is from the scanner picking up a second, broken copy.

Fix Action

Workaround

Delete the nested copy manually:

rm -rf ~/.openclaw/extensions/opik-openclaw/node_modules/openclaw

Opik continues to work — it only imports openclaw/plugin-sdk at runtime, which resolves through Node's module resolution chain to the global install.

Code Example

[plugins] diffs failed to load from /Users/<user>/.openclaw/extensions/opik-openclaw/node_modules/openclaw/dist/extensions/diffs/index.js:
Error: Cannot find module '@pierre/diffs'

---

openclaw plugins install opik-openclaw

---

ls ~/.openclaw/extensions/opik-openclaw/node_modules/openclaw/dist/extensions/diffs/

---

grep "diffs failed to load" /tmp/openclaw/openclaw-*.log

---

rm -rf ~/.openclaw/extensions/opik-openclaw/node_modules/openclaw
RAW_BUFFERClick to expand / collapse

Bug Description

When the opik-openclaw extension is installed, the gateway plugin scanner discovers and attempts to load the diffs extension from a nested openclaw copy inside the opik extension's node_modules/, failing with:

[plugins] diffs failed to load from /Users/<user>/.openclaw/extensions/opik-openclaw/node_modules/openclaw/dist/extensions/diffs/index.js:
Error: Cannot find module '@pierre/diffs'

This repeats on every gateway start/reload (8 times across 2 reloads in our case).

Root Cause

  1. opik-openclaw declares openclaw as a peerDependency (>=2026.3.2)
  2. npm install resolves this by placing a full 209MB copy of openclaw at ~/.openclaw/extensions/opik-openclaw/node_modules/openclaw/
  3. That nested copy includes dist/extensions/diffs/index.js (the diffs extension entry point)
  4. But @pierre/diffs is not installed in the nested copy's dependency tree — it's only installed in the real openclaw at /opt/homebrew/lib/node_modules/openclaw/dist/extensions/diffs/node_modules/
  5. The gateway plugin scanner walks into the nested copy, finds the diffs entry point, and tries to load it → Cannot find module @pierre/diffs

The real diffs extension at the stock path loads fine. The error is from the scanner picking up a second, broken copy.

Impact

  • 8 error log entries per gateway start (noisy but not fatal)
  • The diffs tool still works because the stock copy loads successfully
  • The nested openclaw copy wastes 209MB of disk
  • Could confuse other extensions that get discovered twice from different paths

Reproduction

  1. Install opik-openclaw extension:
    openclaw plugins install opik-openclaw
  2. Verify nested copy exists:
    ls ~/.openclaw/extensions/opik-openclaw/node_modules/openclaw/dist/extensions/diffs/
  3. Start or restart gateway
  4. Check logs:
    grep "diffs failed to load" /tmp/openclaw/openclaw-*.log

Suggested Fixes (any one would work)

  1. Plugin scanner exclusion: Skip extension discovery inside node_modules/ subdirectories of other extensions. The scanner should only look for extensions at the two declared source roots (stock: and global:), not recurse into transitive dependency trees.

  2. opik-openclaw packaging fix: Add openclaw to npm bundledDependencies exclusion or configure it so npm doesn't install the peer dep locally. Alternatively, the opik extension could list openclaw in peerDependenciesMeta with { "optional": true } to prevent npm from auto-installing it.

  3. Graceful dedup: If the scanner finds the same extension ID from multiple paths, prefer the stock source and skip duplicates silently (or with a debug-level log instead of ERROR).

Workaround

Delete the nested copy manually:

rm -rf ~/.openclaw/extensions/opik-openclaw/node_modules/openclaw

Opik continues to work — it only imports openclaw/plugin-sdk at runtime, which resolves through Node's module resolution chain to the global install.

Environment

  • OpenClaw: 2026.3.23-2 (7ffe7e4)
  • opik-openclaw: 0.2.9
  • OS: macOS Tahoe 26.4 (Darwin 25.3.0, arm64)
  • Node: v22.22.0

Related

  • #55375 (cron delivery channel resolution failure — discovered during the same investigation)

extent analysis

Fix Plan

To resolve the issue, we will implement the Plugin scanner exclusion fix. This involves modifying the plugin scanner to skip extension discovery inside node_modules/ subdirectories of other extensions.

Step-by-Step Solution

  1. Modify the plugin scanner:
    • Update the scanner to check if the extension path is inside a node_modules/ directory.
    • If it is, skip the extension and continue with the next one.
  2. Example code:

const path = require('path');

// ...

function isNodeModulesDir(extensionPath) { const nodeModulesDir = path.join(path.dirname(extensionPath), 'node_modules'); return extensionPath.startsWith(nodeModulesDir); }

// ...

extensions.forEach((extension) => { if (isNodeModulesDir(extension.path)) { // Skip this extension return; } // Load the extension loadExtension(extension); });

3. **Verify the fix**:
   * Restart the gateway and check the logs for the "diffs failed to load" error.
   * The error should no longer appear.

### Verification
To verify that the fix worked, restart the gateway and check the logs for the "diffs failed to load" error. The error should no longer appear, indicating that the plugin scanner is correctly skipping the nested `openclaw` copy.

### Extra Tips
* To prevent similar issues in the future, consider implementing a **Graceful dedup** mechanism, which prefers the stock source and skips duplicates silently.
* When packaging extensions, consider adding dependencies to `bundledDependencies` exclusion or configuring them as optional to prevent npm from auto-installing them.

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