Skip to content

fix: preserve manually-added plugin load paths on config sync#1879

Open
gvaiis wants to merge 5 commits intonetease-youdao:mainfrom
gvaiis:fix-preserve-plugin-load-paths
Open

fix: preserve manually-added plugin load paths on config sync#1879
gvaiis wants to merge 5 commits intonetease-youdao:mainfrom
gvaiis:fix-preserve-plugin-load-paths

Conversation

@gvaiis
Copy link
Copy Markdown

@gvaiis gvaiis commented May 2, 2026

Problem

When LobsterAI writes openclaw.json via OpenClawConfigSync.sync(), it replaces plugins.load.paths with only the LobsterAI-managed third-party extensions directory. Any paths added manually (e.g., by running
pm install for community plugins like memory-lancedb-pro) are silently discarded, causing the OpenClaw gateway to fail on restart.

Root Cause

In src/main/libs/openclawConfigSync.ts line ~1458, the load object is completely replaced instead of merged:

...existingPlugins correctly spreads existing plugin config, but the subsequent load: { paths: [thirdPartyDir] } overwrites the entire load object.

Fix

Merge existing load.paths with the third-party extension directory instead of replacing. Deduplicates while keeping order.

Steps to Reproduce

  1. Manually add a path to plugins.load.paths in openclaw.json
  2. Enable any channel in LobsterAI UI (triggers config sync)
  3. The manually-added path is removed from the file
  4. Gateway fails to find manually-installed plugins on restart

When OpenClawConfigSync.sync() writes openclaw.json, it replaces
plugins.load.paths with only the LobsterAI-managed third-party
extensions directory, discarding any paths added manually by the user.

Instead of replacing the entire load object, merge the existing
paths with the third-party dir, deduplicating in order.

Fixes: plugins.load.paths loss after any UI-triggered config sync
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 感谢你提交第一个 Pull Request!欢迎参与 LobsterAI 社区。

请确认 PR 已满足以下要求:

  • 遵循 Conventional Commits 规范
  • 包含清晰的变更说明
  • UI 变更附上截图
  • 通过所有 CI 检查

维护者会尽快 Review,感谢你的贡献!


👋 Thanks for your first pull request to LobsterAI! We appreciate your contribution.

Please make sure your PR:

  • Follows the Conventional Commits spec
  • Includes a clear description of the changes
  • Has screenshots for UI changes
  • Passes all CI checks

A maintainer will review your PR soon. Thank you! 🚀

OpenClaw-Fix-Bot added 4 commits May 2, 2026 06:16
…sync

When LobsterAI rewrites openclaw.json via sync(), manually added
plugins.load.paths entries for npm-installed plugins (e.g.
memory-lancedb-pro) were silently dropped. The previous fix (merge
existing paths with third-party-extensions dir) only recovered paths
that were still in the file at sync time -- but when the file was
already rewritten by a prior sync cycle, those paths were gone.

This change additionally scans the OpenClaw state directory's
node_modules/ for directories containing openclaw.plugin.json and
includes them in load.paths automatically. This ensures that any
plugin installed via npm (or git clone in node_modules) is always
discovered by the gateway, regardless of which earlier writer touched
the config file.
Previously, the sync() method built managedConfig.plugins from a
coworkConfig template + existing file merge, but never scanned
node_modules for user-installed openclaw plugins. If the template or
the existing file's plugins section was minimal (e.g. after a UI
restart that rewrites openclaw.json), npm-installed plugins like
memory-lancedb-pro would be silently dropped from load.paths, slots,
and entries, causing the gateway to fail on next start.

This patch adds a last-mile scan in sync(), right before writeFile:
both stateDir/node_modules and stateDir/../node_modules are searched
for directories containing openclaw.plugin.json. For each discovered
manifest, load.paths, entries[manifest.id], and slots[manifest.kind]
are auto-populated if not already set.

Fixes: netease-youdao#1879
The Force-discover node_modules scan was previously inside the
if(configanged) block, so when config was unchanged the injection
never ran. Move it to always execute, before the configChanged
comparison, so that npm-installed plugins are always injected into
managedConfig regardless of whether the overall config changed.
When the Electron UI starts without an API model configured, it takes the
writeMinimalConfig path instead of full sync. This path rebuilds the config
from a minimal template and can drop npm-installed plugin load.paths.

Add the same node_modules scan that was already added to sync(), so that
npm-installed plugins like memory-lancedb-pro are automatically discovered
in the writeMinimalConfig path too.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant