Skip to content

[Bug]: stock→externalized plugin migration is unblockable on 5.12 — doctor's auto-install step early-returns on the exact invalid-config case it's designed to fix #82301

Description

@cjalden

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:

  1. 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).

  2. 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):

  1. sudo npm install -g [email protected]
  2. Restart any bot's gateway → fails: "web_search provider is not available: brave"
  3. sudo -u <bot> -H openclaw plugins install @openclaw/brave-plugin → blocked by config validation
  4. sudo -u <bot> -H openclaw doctor --fix → completes but doesn't install the missing plugins
  5. 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:

  1. 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.

  2. 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.

  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions