Bug Report: stock→externalized plugin migration is blocked — doctor:release-configured-plugin-installs is the intended cure but early-returns on the very condition it's designed to fix
Environment
- OpenClaw Core (current): 2026.4.29
- OpenClaw Core (candidate): 2026.5.12
- OS: macOS (Apple Silicon)
- Affected plugins on bots:
brave, slack, discord (all bundled in 4.29, externalized as @openclaw/brave-plugin, @openclaw/slack, @openclaw/discord in 5.12 per the 5.12 release note: "Plugins: externalize Slack, OpenShell sandbox, and Anthropic Vertex…").
Summary
Upgrading from a pre-externalization release (2026.4.29) to 2026.5.12 has no clean operator path:
-
Pre-upgrade install on the OLD runtime is narrow / impossible. openclaw plugins install @openclaw/brave-plugin (no version pin) fails: "Plugin requires plugin API >=2026.5.12, but this OpenClaw runtime exposes 2026.4.29". The error doesn't mention that older versions may be compatible. Most plugins have only one or zero 4.29-compatible versions on npm — slack has zero (its earliest published version, 2026.5.12-beta.7, already requires pluginApi >= 2026.5.12-beta.7).
-
Post-upgrade install on the NEW runtime is blocked by config validation. After npm install -g [email protected], gateways crash-loop:
Gateway failed to start: Invalid config at /Users/kit/.openclaw/openclaw.json.
tools.web.search.provider: web_search provider is not available: brave
(install or enable plugin "brave", then run openclaw doctor --fix)
Running the suggested fix:
$ sudo -u kit -H openclaw plugins install @openclaw/brave-plugin
OpenClaw config is invalid
- tools.web.search.provider: web_search provider is not available: brave
(install or enable plugin "brave", then run openclaw doctor --fix)
Fix: openclaw doctor --fix
openclaw plugins install itself is gated by config validation, so it can't install the plugin whose absence makes the config invalid. openclaw doctor --fix runs but skips its plugin-install repair step (see "Root Cause" below).
Root Cause (verified against 2026.5.12 source)
The migration helper exists in upstream code — dist/doctor-health-contributions-__CSp6bj.js:
async function runReleaseConfiguredPluginInstallsHealth(ctx) {
if (!ctx.sourceConfigValid) return; // ← bails on the case it's designed to fix
if (!ctx.prompter.shouldRepair) return;
const { maybeRunConfiguredPluginInstallReleaseStep } =
await import("./release-configured-plugin-installs-DqpmRyu1.js");
…
}
And in release-configured-plugin-installs-DqpmRyu1.js:
async function maybeRunConfiguredPluginInstallReleaseStep(params) {
…
const configured = collectReleaseConfiguredPluginIds({ cfg, env });
…
const repaired = await repairMissingPluginInstallsForIds({
cfg, pluginIds: configured.pluginIds, channelIds: configured.channelIds, …
});
}
repairMissingPluginInstallsForIds is exactly the right primitive — it walks the config's plugin/channel references and installs the missing externalized plugins. But the outer gate if (!ctx.sourceConfigValid) return prevents it from running when config is invalid, which is precisely the post-stock→externalized migration scenario.
Steps to Reproduce
On a 4.29 host with bots whose openclaw.json enables stock brave, slack, or discord (via plugins.entries, channels.<id>.enabled, or tools.web.search.provider):
sudo npm install -g [email protected]
- Restart any bot's gateway → fails: "web_search provider is not available: brave"
sudo -u <bot> -H openclaw plugins install @openclaw/brave-plugin → blocked by config validation
sudo -u <bot> -H openclaw doctor --fix → completes but doesn't install the missing plugins
- Bot stays in restart-loop until openclaw is rolled back
Narrow Workaround (verified, not generally applicable)
For brave and discord specifically, there is exactly one published 4.29-compatible version each (@openclaw/[email protected], @openclaw/[email protected], both declaring compat.pluginApi: ">=2026.4.10" or >=2026.4.25). Pinning to those versions on the OLD runtime works:
$ sudo -u kit -H openclaw plugins install @openclaw/[email protected]
…
ClawHub code-plugin @openclaw/[email protected] channel=official
Compatibility: pluginApi=>=2026.4.10 minGateway=>=2026.4.10
…installed cleanly.
But the install error message in step 3 doesn't surface this, and @openclaw/slack has no such version. Each subsequent plugin release pins compat.pluginApi lock-step with its own openclaw version (5.5 → ">=5.5", 5.7 → ">=5.7", 5.12 → ">=5.12"), so the pre-staging window is one beta-release wide and closed for slack entirely.
Suggested Fix
Any one of these would unblock the migration:
-
Relax the gate on runReleaseConfiguredPluginInstallsHealth. When sourceConfigValid is false specifically because of missing-externalized-plugin references (detectable by the validation error code), let the auto-install step run — that's the cure. Re-validate after.
-
Add a flag to plugins install that bypasses config validation. E.g. openclaw plugins install --ignore-config-errors @openclaw/brave-plugin. The install command itself doesn't depend on the rest of the config being loadable.
-
Improve the install error for INCOMPATIBLE_PLUGIN_API to query the registry for the newest compatible version and suggest pinning, instead of just stating the failed version's requirement. Doesn't fix slack but helps the brave/discord cases.
Without one of these, the documented upgrade path for any pod with stock brave/slack/discord in its config is effectively "roll back and wait."
What I checked
openclaw plugins install --help — no flag to bypass config validation
openclaw doctor --help — no flag to force plugin installs against invalid config
openclaw doctor --fix source path: runReleaseConfiguredPluginInstallsHealth early-returns on !ctx.sourceConfigValid
- All 36 versions of
@openclaw/brave-plugin, 60 of @openclaw/discord, 5 of @openclaw/slack on npm: compat ranges per version above
Bug Report: stock→externalized plugin migration is blocked —
doctor:release-configured-plugin-installsis the intended cure but early-returns on the very condition it's designed to fixEnvironment
brave,slack,discord(all bundled in 4.29, externalized as@openclaw/brave-plugin,@openclaw/slack,@openclaw/discordin 5.12 per the 5.12 release note: "Plugins: externalize Slack, OpenShell sandbox, and Anthropic Vertex…").Summary
Upgrading from a pre-externalization release (2026.4.29) to 2026.5.12 has no clean operator path:
Pre-upgrade install on the OLD runtime is narrow / impossible.
openclaw plugins install @openclaw/brave-plugin(no version pin) fails: "Plugin requires plugin API >=2026.5.12, but this OpenClaw runtime exposes 2026.4.29". The error doesn't mention that older versions may be compatible. Most plugins have only one or zero 4.29-compatible versions on npm — slack has zero (its earliest published version, 2026.5.12-beta.7, already requirespluginApi >= 2026.5.12-beta.7).Post-upgrade install on the NEW runtime is blocked by config validation. After
npm install -g [email protected], gateways crash-loop:Running the suggested fix:
openclaw plugins installitself is gated by config validation, so it can't install the plugin whose absence makes the config invalid.openclaw doctor --fixruns but skips its plugin-install repair step (see "Root Cause" below).Root Cause (verified against 2026.5.12 source)
The migration helper exists in upstream code —
dist/doctor-health-contributions-__CSp6bj.js:And in
release-configured-plugin-installs-DqpmRyu1.js:repairMissingPluginInstallsForIdsis exactly the right primitive — it walks the config's plugin/channel references and installs the missing externalized plugins. But the outer gateif (!ctx.sourceConfigValid) returnprevents it from running when config is invalid, which is precisely the post-stock→externalized migration scenario.Steps to Reproduce
On a 4.29 host with bots whose
openclaw.jsonenables stockbrave,slack, ordiscord(viaplugins.entries,channels.<id>.enabled, ortools.web.search.provider):sudo npm install -g [email protected]sudo -u <bot> -H openclaw plugins install @openclaw/brave-plugin→ blocked by config validationsudo -u <bot> -H openclaw doctor --fix→ completes but doesn't install the missing pluginsNarrow Workaround (verified, not generally applicable)
For
braveanddiscordspecifically, there is exactly one published 4.29-compatible version each (@openclaw/[email protected],@openclaw/[email protected], both declaringcompat.pluginApi: ">=2026.4.10"or>=2026.4.25). Pinning to those versions on the OLD runtime works:But the install error message in step 3 doesn't surface this, and
@openclaw/slackhas no such version. Each subsequent plugin release pinscompat.pluginApilock-step with its own openclaw version (5.5 → ">=5.5", 5.7 → ">=5.7", 5.12 → ">=5.12"), so the pre-staging window is one beta-release wide and closed for slack entirely.Suggested Fix
Any one of these would unblock the migration:
Relax the gate on
runReleaseConfiguredPluginInstallsHealth. WhensourceConfigValidis false specifically because of missing-externalized-plugin references (detectable by the validation error code), let the auto-install step run — that's the cure. Re-validate after.Add a flag to
plugins installthat bypasses config validation. E.g.openclaw plugins install --ignore-config-errors @openclaw/brave-plugin. The install command itself doesn't depend on the rest of the config being loadable.Improve the install error for
INCOMPATIBLE_PLUGIN_APIto query the registry for the newest compatible version and suggest pinning, instead of just stating the failed version's requirement. Doesn't fix slack but helps the brave/discord cases.Without one of these, the documented upgrade path for any pod with stock
brave/slack/discordin its config is effectively "roll back and wait."What I checked
openclaw plugins install --help— no flag to bypass config validationopenclaw doctor --help— no flag to force plugin installs against invalid configopenclaw doctor --fixsource path:runReleaseConfiguredPluginInstallsHealthearly-returns on!ctx.sourceConfigValid@openclaw/brave-plugin, 60 of@openclaw/discord, 5 of@openclaw/slackon npm: compat ranges per version above