openclaw - ✅(Solved) Fix maybeThrowOnPluginLoadError fires before plugin.allow filter, blocking CLI boot [1 pull requests, 1 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#63575Fetched 2026-04-10 03:42:42
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
referenced ×2commented ×1cross-referenced ×1

Error Message

Error: Plugin load errors: brave, slack at maybeThrowOnPluginLoadError (/opt/homebrew/lib/node_modules/openclaw/dist/loader-BSIqIOsD.js:2208:...) at loadPluginsFromConfig (/opt/homebrew/lib/node_modules/openclaw/dist/loader-BSIqIOsD.js:2195:...) at boot (/opt/homebrew/lib/node_modules/openclaw/dist/loader-BSIqIOsD.js:...)

Fix Action

Workaround

Local hot-patch applied in dist/loader-BSIqIOsD.js at line 2205 (see diff above). This is not a sustainable long-term fix — the architecture needs the filter to run before the throw.

PR fix notes

PR #63586: fix(plugins): ignore non-allowlisted load errors #63575

Description (problem / solution / changelog)

Summary

  • Problem: Gateway/CLI bootstrap can crash on strict plugin loading when non-allowlisted plugins end up in status === "error".
  • Why it matters: Users rely on plugins.allow to scope trusted/loaded plugins; failures outside the allowlist should not hard-fail boot.
  • What changed: Strict load failure throwing is now filtered by plugins.allow (when non-empty), and the thrown error summary only includes allowlisted failures.
  • What did NOT change (scope boundary): When plugins.allow is empty (open allowlist), strict behavior remains unchanged.

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

  • Fixes #63575

User-visible / Behavior Changes

  • When plugins.allow is set (non-empty), strict plugin load errors will only throw if an allowlisted plugin failed to load/register. Errors from plugins outside the allowlist are tolerated (with diagnostics).

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)

Repro + Verification

Environment

  • OS: Linux
  • Runtime/container: Node (repo default tooling)
  • Relevant config (redacted): plugins.allow non-empty

Tests

  • pnpm test src/plugins/loader.test.ts -t "filters strict plugin load failures by plugins.allow|throws when strict plugin loading sees plugin errors"

Evidence

  • Passing targeted test(s) (see above)

Human Verification (required)

  • Verified scenarios:
    • Allowlisted plugin failure still throws under strict loading.
    • Non-allowlisted failures are filtered out of strict throw decision and error summary when plugins.allow is non-empty.
  • Edge cases checked:
    • plugins.allow empty preserves existing strict behavior.
  • What I did not verify:
    • Full gateway boot with real third-party plugins (requires external credentials/config).

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)

Risks and Mitigations

  • Risk: Filtering could mask non-allowlisted failures in strict mode.
    • Mitigation: Only applies when plugins.allow is explicitly set (non-empty), matching user intent to scope trusted/loaded plugins.

Changed files

  • src/plugins/loader.test.ts (modified, +102/-0)
  • src/plugins/loader.ts (modified, +34/-5)

Code Example

Error: Plugin load errors: brave, slack
    at maybeThrowOnPluginLoadError (/opt/homebrew/lib/node_modules/openclaw/dist/loader-BSIqIOsD.js:2208:...)
    at loadPluginsFromConfig (/opt/homebrew/lib/node_modules/openclaw/dist/loader-BSIqIOsD.js:2195:...)
    at boot (/opt/homebrew/lib/node_modules/openclaw/dist/loader-BSIqIOsD.js:...)

---

--- a/loader-BSIqIOsD.js (maybeThrowOnPluginLoadError, around line 2208)
+++ b/loader-BSIqIOsD.js
@@ -2205,8 +2205,12 @@ function maybeThrowOnPluginLoadError(registry, throwOnLoadError) {
   if (!throwOnLoadError) return;
   const errorred = registry.plugins.filter((entry) => entry.status === "error");
   if (errored.length === 0) return;
-  throw new Error(`Plugin load errors: ${errored.map(e => e.id).join(", ")}`);
+  // HOT-PATCH (Claudio 2026-04-08, reapplied for 2026.4.9 loader-BSIqIOsD.js):
+  // Secret resolver ordering bug — CLI load-time tries to resolve SecretRefs
+  // before gateway runtime snapshot is active. Tolerate and warn instead of throw.
+  console.warn(`[openclaw hot-patch] plugin load errors tolerated: ${errored.map(e => e.id).join(", ")}`);
+  return;
 }
RAW_BUFFERClick to expand / collapse

Version

openclaw 2026.4.9 (commit ac782bcd32ff3fb93fbac38ee5785dd2ccd95bad)

Problem

During CLI/gateway boot, plugin load errors that are filterable via plugins.allow are thrown before the filter runs, breaking boot when a non-allowed plugin fails to load.

The function maybeThrowOnPluginLoadError (loader-BSIqIOsD.js) unconditionally throws if any plugin has status === "error"", without checking whether that plugin is in the plugins.allowallowlist. Sinceplugins.allow` is evaluated later in the bootstrap sequence, valid errors (e.g. from plugins not in the allowlist) cause a hard crash instead of being silently tolerated.

Repro

  1. Have a plugin that fails to load (e.g. brave with a bad/placeholder API key, or slack with missing bot token)
  2. Ensure that plugin is not in plugins.allow list
  3. Boot the gateway — it throws and exits instead of warning and continuing

Original Stack

Error: Plugin load errors: brave, slack
    at maybeThrowOnPluginLoadError (/opt/homebrew/lib/node_modules/openclaw/dist/loader-BSIqIOsD.js:2208:...)
    at loadPluginsFromConfig (/opt/homebrew/lib/node_modules/openclaw/dist/loader-BSIqIOsD.js:2195:...)
    at boot (/opt/homebrew/lib/node_modules/openclaw/dist/loader-BSIqIOsD.js:...)

Patch Diff

--- a/loader-BSIqIOsD.js (maybeThrowOnPluginLoadError, around line 2208)
+++ b/loader-BSIqIOsD.js
@@ -2205,8 +2205,12 @@ function maybeThrowOnPluginLoadError(registry, throwOnLoadError) {
   if (!throwOnLoadError) return;
   const errorred = registry.plugins.filter((entry) => entry.status === "error");
   if (errored.length === 0) return;
-  throw new Error(`Plugin load errors: ${errored.map(e => e.id).join(", ")}`);
+  // HOT-PATCH (Claudio 2026-04-08, reapplied for 2026.4.9 loader-BSIqIOsD.js):
+  // Secret resolver ordering bug — CLI load-time tries to resolve SecretRefs
+  // before gateway runtime snapshot is active. Tolerate and warn instead of throw.
+  console.warn(`[openclaw hot-patch] plugin load errors tolerated: ${errored.map(e => e.id).join(", ")}`);
+  return;
 }

Expected Behavior

Plugins not in plugins.allow that fail to load should produce a warning, not a hard error that crashes the gateway. The plugins.allow filter should be consulted before deciding whether to throw.

Workaround

Local hot-patch applied in dist/loader-BSIqIOsD.js at line 2205 (see diff above). This is not a sustainable long-term fix — the architecture needs the filter to run before the throw.

extent analysis

TL;DR

Apply a patch to modify the maybeThrowOnPluginLoadError function to check the plugins.allow filter before throwing an error on plugin load failure.

Guidance

  • Identify the plugins that are not in the plugins.allow list and are causing the load errors.
  • Modify the maybeThrowOnPluginLoadError function to check the plugins.allow filter before throwing an error, similar to the provided patch diff.
  • Verify that the modified function correctly tolerates plugin load errors for plugins not in the plugins.allow list and only produces a warning.
  • Consider refactoring the architecture to ensure the plugins.allow filter runs before the maybeThrowOnPluginLoadError function to provide a long-term fix.

Example

--- a/loader-BSIqIOsD.js (maybeThrowOnPluginLoadError, around line 2208)
+++ b/loader-BSIqIOsD.js
@@ -2205,8 +2205,12 @@ function maybeThrowOnPluginLoadError(registry, throwOnLoadError) {
   if (!throwOnLoadError) return;
   const errorred = registry.plugins.filter((entry) => entry.status === "error" && !plugins.allow.includes(entry.id));
   if (errored.length === 0) return;
   console.warn(`[openclaw hot-patch] plugin load errors tolerated: ${errored.map(e => e.id).join(", ")}`);
   return;
 }

Notes

The provided patch diff is a local hot-patch and not a sustainable long-term fix. The architecture needs to be refactored to ensure the plugins.allow filter runs before the maybeThrowOnPluginLoadError function.

Recommendation

Apply a workaround by modifying the maybeThrowOnPluginLoadError function to check the plugins.allow filter before throwing an error, as shown in the example above. This will provide a temporary fix until a long-term architectural refactor can be implemented.

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