Skip to content

fix(gateway): warn at startup when a configured channel is blocked from loading#93657

Closed
Alix-007 wants to merge 1 commit into
openclaw:mainfrom
Alix-007:fix/slack-plugin-allowlist-regression
Closed

fix(gateway): warn at startup when a configured channel is blocked from loading#93657
Alix-007 wants to merge 1 commit into
openclaw:mainfrom
Alix-007:fix/slack-plugin-allowlist-regression

Conversation

@Alix-007

Copy link
Copy Markdown
Contributor

Summary

Re #91873. After upgrading to 2026.6.x, a Slack (or any global/config-origin) channel that the user had configured under channels.* but did not list in plugins.allow (or enable via plugins.entries.<id>.enabled) is dropped by the plugin trust gate — and the gateway startup is completely silent about it. The user sees the ready banner (http server listening (N plugins: ...)) with no error, no warning, and their Slack channel just stops working. The reporter confirmed the workaround is plugins.allow=["slack"].

The trust gate itself (channel-presence-policy / gateway-startup-plugin-ids) is intentional and unchanged here — whether to restore implicit loading for upgraded configs is a product decision and is out of scope for this PR. This change only makes the silent drop loud, which is what reviewers asked for on the issue ("surface blocked configured channels in gateway startup/status/doctor before users miss messages").

Changes

  • src/gateway/server-startup-log.tslogGatewayStartup now reuses the existing doctor blocker scan (scanConfiguredChannelPluginBlockers / collectConfiguredChannelPluginBlockerWarnings) and emits a startup warning for each configured channel that was blocked from loading, e.g. configured channel not loaded: channels.slack: <reason>. Add plugins.entries.slack.enabled=true .... Wrapped in try/catch — the warning is advisory and never blocks startup. No change to trust-gate semantics, no restored implicit loading, no fallback shim.

Real behavior proof

Behavior addressed: a configured-but-untrusted channel that the gateway drops now produces a startup warning instead of disappearing silently.

Real environment: local, Node v22. Drove the real logGatewayStartup → real scanConfiguredChannelPluginBlockers / blocker-warning collection → real trust-gate decision (evaluateEffectiveChannelPlugin), with only the on-disk manifest discovery injected via the project's standard test seam (vi.spyOn(loadPluginManifestRegistry) with a real global-origin slack manifest record).

Evidence (before/after, real functions):

pre-fix (real source via git stash):  warnings for channels.slack = []        → SILENT (reproduces the bug)
post-fix:                             warnings for channels.slack = 1 warning  → "configured channel not loaded: channels.slack: ... Add plugins.entries.slack.enabled=true ..."
with plugins.allow=["slack"]:         no warning (channel loads)

Observed result: the blocked channel is surfaced at startup after the fix; the pre-fix function emits nothing. A trust-pre-check (resolveConfiguredChannelPresencePolicy) confirms global-origin slack is effective:false / blockedReasons:["untrusted-plugin"] without plugins.allow and effective:true once it's listed — matching the reporter's workaround exactly.

What was not tested: no live Slack connection (not needed — this is the config/discovery/startup-logging path); restoring implicit auto-load is deliberately not attempted (product decision).

Tests and validation

  • src/gateway/server-startup-log.test.ts (+2): warns with channels.slack + the enable hint when the channel is blocked; no warning once plugins.allow includes it. 10/10 pass.
  • Negative control: reverting the change makes the positive test fail (empty warnings = silent), confirming the warning comes from this fix.
  • npx oxlint --import-plugin clean on both changed files.

…d at startup

After the plugin-discovery trust gate change, an installed global/npm channel
plugin (e.g. Slack at ~/.openclaw/npm/projects/) that is not explicitly trusted
via plugins.allow or plugins.entries[id].enabled is filtered out of the startup
plan. The gateway logged "http server listening (N plugins: ...)" with the
channel silently absent — operators had no signal their configured channel was
down until they tried to use it (issue openclaw#91873, impact:message-loss).

Reuse the existing doctor blocker scan (scanConfiguredChannelPluginBlockers /
collectConfiguredChannelPluginBlockerWarnings) inside logGatewayStartup to emit
a loud per-channel warning that names the channel and the exact config fix. This
does not change the plugin-trust policy or restore implicit auto-loading; it only
turns a silent omission into a visible diagnostic, matching the issue's second
ask and the reviewer's preferred startup/status warning path.
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 16, 2026
@vincentkoc vincentkoc self-assigned this Jun 16, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Closing this because it is not the right owner boundary or the best fix for the blocked-channel upgrade case. Gateway startup should consume prepared plugin/startup facts; importing doctor scanning here re-runs broad manifest/config discovery on every startup and silently swallows failures, while only warning instead of resolving the compatibility problem. The viable direction is an explicit migration/compat decision or a narrow blocked-channel fact carried into startup/status without a second discovery path.

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

Labels

gateway Gateway runtime size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants