openclaw - 💡(How to fix) Fix [Bug]: `openclaw message send` CLI loads the full plugin registry on every call [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

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#73006Fetched 2026-04-28 06:28:45
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
closed ×1commented ×1mentioned ×1subscribed ×1

Sending a message via openclaw message send ends up loading every plugin shipped with openclaw before doing the send. With ~88 bundled plugins on this install that is 2-3 minutes of CPU on a Pi 500, even when you just want to deliver one Discord message. The command only needs the channel it is sending to.

Root Cause

Sending a message via openclaw message send ends up loading every plugin shipped with openclaw before doing the send. With ~88 bundled plugins on this install that is 2-3 minutes of CPU on a Pi 500, even when you just want to deliver one Discord message. The command only needs the channel it is sending to.

Fix Action

Fix / Workaround

I worked around this on my box with a one-line dist patch in register.message-*.js:

Code Example

time openclaw message send --channel discord --target <id> --dry-run -m "x"

---

time openclaw message send --channel discord --target <id> --dry-run -m "x"

---

ensurePluginRegistryLoaded(opts.channel ? { onlyPluginIds: [opts.channel] } : { scope: "configured-channels" });
RAW_BUFFERClick to expand / collapse

Bug type

Bug (CLI scope defaults to "all", loads every plugin manifest just to send one message)

Beta release blocker

No

Summary

Sending a message via openclaw message send ends up loading every plugin shipped with openclaw before doing the send. With ~88 bundled plugins on this install that is 2-3 minutes of CPU on a Pi 500, even when you just want to deliver one Discord message. The command only needs the channel it is sending to.

Steps to reproduce

  1. Run openclaw 2026.4.25
  2. Time a single CLI message send:
time openclaw message send --channel discord --target <id> --dry-run -m "x"

Expected behaviour

A CLI invocation that knows its target channel ahead of time should load only that channel's plugin (or at most the configured channels), not every plugin in the install.

Actual behaviour

The function that handles message-send (runMessageAction in dist/register.message-*.js) calls the registry loader without telling it which plugin it actually needs. The loader's default behaviour is to scan every plugin directory under dist/extensions/, open each openclaw.plugin.json, and parse the contents. The send itself only needs the channel plugin's manifest.

The loader does support narrower modes - "only configured channels", "only one specific plugin id" - but the message-send code path does not pass any of them, so it always gets the full scan.

OpenClaw version

2026.4.25

Environment

Raspberry Pi 500 (Debian Trixie, aarch64). Gateway runs as a systemd user service. Many side-of-house scripts use openclaw message send (boot-check posts two reports per gateway restart, cron jobs deliver to Discord).

Logs, screenshots, and evidence

Standalone timing on a healthy gateway:

time openclaw message send --channel discord --target <id> --dry-run -m "x"
Scope passedWall time
(default "all")~2m30s
{ scope: "configured-channels" } (2 channels here)1m9s
{ onlyPluginIds: [opts.channel] }10.7s

CPU is almost entirely on the V8 main thread. V8 --prof capture during a separate gateway boot showed ~52% of all JS CPU time inside node_modules/json5/lib/parse.js - that is the manifest parse path, hit once per plugin during the registry load. So the cost is real per-call work, not stale gateway state.

Code pointers on this install:

  • dist/register.message-CaRx3OC0.js line 113 - runMessageAction calls ensurePluginRegistryLoaded() with no args
  • dist/runtime-registry-loader-fxcQDWv8.js line 40 - const scope = options?.scope ?? "all"

Bundle filenames will rotate per release.

Impact and severity

Affected: anything that shells out to openclaw message send. On this install:

  • boot-check posts two reports to Discord per gateway restart, costing ~5 minutes of CPU between them
  • Family cron jobs (chore reports, football updates) each pay 2-3 min when they fire
  • Manual openclaw message send from the shell takes 2-3 min before the message even leaves

Severity: high on slow hardware, medium elsewhere. CPU is taken from whatever else is running, so on a Pi 500 this competes with the gateway's own startup work after a restart and stretches channel startup out further than necessary.

Frequency: every CLI invocation.

Additional information

I worked around this on my box with a one-line dist patch in register.message-*.js:

ensurePluginRegistryLoaded(opts.channel ? { onlyPluginIds: [opts.channel] } : { scope: "configured-channels" });

CLI message send dropped from 2m30s to ~10s.

extent analysis

TL;DR

Passing the target channel to the registry loader can significantly reduce the loading time of plugins.

Guidance

  • The runMessageAction function in register.message-*.js should be modified to pass the target channel to ensurePluginRegistryLoaded to avoid loading all plugins.
  • The ensurePluginRegistryLoaded function can be called with an options object containing onlyPluginIds set to the target channel, like { onlyPluginIds: [opts.channel] }.
  • This change can be verified by measuring the time it takes to send a message using the openclaw message send command.
  • The fix can be applied by modifying the register.message-*.js file to include the one-line patch provided in the issue description.

Example

ensurePluginRegistryLoaded(opts.channel ? { onlyPluginIds: [opts.channel] } : { scope: "configured-channels" });

Notes

  • This fix assumes that the target channel is known ahead of time and can be passed to the registry loader.
  • The performance improvement will be most noticeable on slow hardware, such as the Raspberry Pi 500.

Recommendation

Apply the workaround by modifying the register.message-*.js file to include the one-line patch, as it significantly reduces the loading time of plugins and improves performance.

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