Skip to content

fix #90333: [Bug]: Discord image build aborts at step 66 — openclaw-build-messaging-plugins.py exits 1#92869

Merged
vincentkoc merged 2 commits into
openclaw:mainfrom
zhangguiping-xydt:feat/issue-90333
Jun 14, 2026
Merged

fix #90333: [Bug]: Discord image build aborts at step 66 — openclaw-build-messaging-plugins.py exits 1#92869
vincentkoc merged 2 commits into
openclaw:mainfrom
zhangguiping-xydt:feat/issue-90333

Conversation

@zhangguiping-xydt

Copy link
Copy Markdown
Contributor

Summary

What problem does this PR solve?

Root cause: the official external plugin recovery resolver used the raw install spec as the identity key, so the versioned npm spec @openclaw/discord@2026.5.22 did not resolve to the catalog source identity @openclaw/discord. That resolver miss caused the invalid-config recovery path to preserve the stale plugins.load.paths entry, and config validation rejected the write after the install action.

Why does this matter now?

NemoClaw onboarding can select Discord, then the image build runs the versioned Discord install command from the generated build script. When the previous Discord plugin path is missing, the build cannot finish even though this is exactly the kind of stale plugin state the recovery install path is meant to repair.

What is the intended outcome?

Fix classification: root-cause fix. The installer now maps versioned official npm specs back to their package name for recovery metadata, and the recovery config removes only validation-reported missing plugin load paths before persisting the repaired install state.

What is intentionally out of scope?

What did NOT change: this PR does not change Discord runtime auth, live bot connection behavior, marketplace override semantics, plugin schema defaults, migration files, unrelated plugin load paths, or non-recovery install behavior.

What does success look like?

A stale Discord plugin config that previously blocked plugins install @openclaw/discord@2026.5.22 now installs successfully and validates afterward.

What should reviewers focus on?

Why this is root-cause fix: the source boundary is the install-spec resolver and official external plugin catalog mapping, not the Docker build script. The patch parses the npm spec to its package identity before matching catalog recovery metadata, then applies the config validation invariant at persistence time by removing only the load path that validation proved missing. This fixes the resolver/source-of-truth mismatch and the invalid config write source, instead of adding a Discord-only fallback or bypassing config validation.

Patch quality notes: the helper returns null for non-plugins.load.paths issues and for messages without the plugin path not found: marker so unrelated validation errors cannot drive cleanup. The as unknown as OpenClawConfig cast is limited to the existing test style for partial config snapshots. Patch warning/default-return smell is not masking a runtime failure; it is a parser guard that keeps cleanup opt-in to the validation issue shape.

Architecture / source-of-truth check: the source of truth for official external plugin identity remains the official external plugin catalog, and the source of truth for removable stale load paths is the config validation diagnostic. Related open PR / same-contract scan from init found no competing linked PR for this issue. Public contract surface is config compatibility only: existing invalid recovery requests become repairable, while other invalid configs still fail through the same guard.

Linked context

Which issue does this close?

Closes #90333

Which issues, PRs, or discussions are related?

Related PR / competition scan: daily-fix init found no linked open PR for this issue.

Was this requested by a maintainer or owner?

No direct maintainer request beyond the linked issue report.

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: openclaw plugins install @openclaw/discord@2026.5.22 can recover a stale Discord install even when the existing config has channels.discord and a missing plugins.load.paths entry.

  • Real environment tested: local OpenClaw CLI with an isolated temporary OPENCLAW_HOME and config that reproduced the stale Discord plugin path failure.

  • Exact steps or command run after this patch: create a config containing a stale Discord npm install, channels.discord, and plugins.load.paths: ["/missing/discord"]; then run pnpm dev plugins install @openclaw/discord@2026.5.22 followed by pnpm dev config validate.

  • Evidence after fix (terminal capture, redacted):

    $ node scripts/run-node.mjs plugins install @openclaw/discord@2026.5.22
    OpenClaw config is invalid
    Problem:
      - plugins.load.paths: plugin: plugin path not found: /missing/discord
    
    Fix: openclaw doctor --fix
    Inspect: openclaw config validate
    Status, health, logs, tasks list/audit, and doctor commands still run with invalid config.
    Using bundled plugin "discord" from <repo>/dist/extensions/discord for npm install spec "@openclaw/discord@2026.5.22" because this plugin ships with the current OpenClaw build. To force an external npm override, use npm:@openclaw/discord@2026.5.22.
    Installed plugin: discord
    Restart the gateway to load plugins.
    
    $ node scripts/run-node.mjs config validate
    Config valid: <temp-config>/config.json5
    
  • Observed result after fix: the versioned Discord install completes and the same config validates successfully afterward.

  • What was not tested: a live Discord bot connection or a full NemoClaw Docker image build.

  • Proof limitations or environment constraints: the proof focuses on the failing OpenClaw CLI recovery command from the image build log; no Discord token was needed or used for this config recovery path.

  • Before evidence (optional but encouraged): the new regression test failed before the fix because /gone remained in plugins.load.paths after loadConfigForInstall, which would make the install write fail validation.

Tests and validation

Which commands did you run?

Target test file: src/cli/plugins-install-config.test.ts and src/cli/program/preaction.test.ts.

  • pnpm exec vitest run src/cli/plugins-install-config.test.ts src/cli/program/preaction.test.ts
  • pnpm dev plugins install @openclaw/discord@2026.5.22 with stale Discord config, then pnpm dev config validate
  • pnpm run deps:shrinkwrap:changed:check
  • pnpm run lint -- src/cli/plugin-install-config-policy.ts src/cli/plugins-install-command.ts src/cli/plugins-install-config.test.ts src/cli/program/preaction.test.ts

What regression coverage was added or updated?

Scenario locked in: versioned official npm specs inherit Discord invalid-config recovery metadata, the CLI pre-action guard allows invalid config for plugins install @openclaw/discord@2026.5.22, and recovery install config removes validation-reported missing plugins.load.paths entries before persistence.

What failed before this fix, if known?

Why this is the smallest reliable guardrail: the focused config test failed before the implementation because the missing path stayed in plugins.load.paths; the command proof exercises the same install command shape from the issue and confirms the repaired config validates after install.

If no test was added, why not?

Not applicable; regression tests were added for the resolver/pre-action path and the config cleanup path.

Known validation note: pnpm run check was also run; all preflight guards shown in the output passed except the repository-wide npm shrinkwrap guard, which reported npm-shrinkwrap.json is stale. Run pnpm deps:shrinkwrap:generate. No package or lockfile changes are part of this PR, and deps:shrinkwrap:changed:check passed.

Risk checklist

Did user-visible behavior change? (Yes/No)

Yes.

Did config, environment, or migration behavior change? (Yes/No)

Yes.

Did security, auth, secrets, network, or tool execution behavior change? (Yes/No)

No.

What is the highest-risk area?

Risk labels considered: config compatibility and plugin install availability. The install command now mutates invalid recovery config by dropping missing plugin load paths reported by validation.

How is that risk mitigated?

Why acceptable: the recovery path is still gated to official plugin install requests that opt into invalid-config recovery; cleanup only uses plugins.load.paths validation issues whose message includes plugin path not found:; unrelated load paths are preserved; and non-recovery installs still fail with the existing invalid-config error.

Current review state

What is the next action?

Maintainer-ready confidence: high. Next action is remote CI and maintainer review after PR creation.

What is still waiting on author, maintainer, CI, or external proof?

Waiting on remote CI after PR creation. No author-side follow-up is known from local validation.

Which bot or reviewer comments were addressed?

No bot or reviewer comments yet; this is a new issue fix.

@openclaw-barnacle openclaw-barnacle Bot added cli CLI command changes size: S proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 14, 2026
@clawsweeper

clawsweeper Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 14, 2026, 12:30 PM ET / 16:30 UTC.

Summary
This PR maps versioned official npm plugin specs back to catalog identities and removes validation-reported missing plugins.load.paths entries during official plugin install recovery, with focused CLI tests.

PR surface: Source +199, Tests +389. Total +588 across 4 files.

Reproducibility: yes. Current main's resolver does not normalize a versioned official npm spec to its package identity, and the PR body gives a concrete stale-config CLI command sequence that demonstrates the repaired behavior after the patch.

Review metrics: 1 noteworthy metric.

  • Recovery config mutation: 1 added cleanup path. The PR adds an official-plugin install recovery path that removes validation-reported missing plugins.load.paths, which is compatibility-sensitive before merge.

Stored data model
Persistent data-model change detected: migration/backfill/repair: src/cli/plugins-install-command.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Maintainers should decide whether the CLI recovery proof is enough for the linked build issue or whether full NemoClaw image-build proof is required before merge.

Risk before merge

  • [P1] The install command now mutates invalid recovery config by dropping validation-reported missing plugins.load.paths entries for the requested official plugin, so maintainers should explicitly accept that compatibility behavior for users with stale explicit local paths.
  • [P1] The supplied proof covers the OpenClaw CLI recovery command and follow-up config validation, not a full NemoClaw Docker image build or the later Discord gateway READY/proxy symptom mentioned in the linked issue.

Maintainer options:

  1. Accept the scoped recovery cleanup (recommended)
    Land the PR if maintainers agree that official-plugin reinstall recovery may remove only the requested plugin's validation-proven missing load path.
  2. Request full build proof first
    Ask for a NemoClaw Discord image-build run if closing the linked issue requires proof beyond the OpenClaw CLI recovery command.
  3. Pause if recovery belongs only in doctor
    Pause or close if maintainers decide plugins install should not mutate stale config and this repair should stay exclusively in openclaw doctor --fix.

Next step before merge

  • [P2] No repair lane is needed; the next action is maintainer review of the compatibility-sensitive config cleanup and proof scope.

Security
Cleared: Cleared: the diff changes CLI recovery logic and tests without adding dependencies, workflow permissions, lockfiles, secrets handling, or new third-party execution sources.

Review details

Best possible solution:

Merge only after maintainers accept the scoped config-recovery mutation boundary; track full NemoClaw image-build or Discord gateway proof separately if they want those broader asks resolved before closing the linked issue.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main's resolver does not normalize a versioned official npm spec to its package identity, and the PR body gives a concrete stale-config CLI command sequence that demonstrates the repaired behavior after the patch.

Is this the best way to solve the issue?

Yes for the PR's scoped fix. Resolving the official install-spec identity mismatch and removing only validation-proven stale load paths is a better owner-boundary fix than adding a Discord-specific Docker fallback, though full NemoClaw image proof remains outside this branch.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against aefd49909d41.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal proof from a local OpenClaw CLI setup with isolated config showing the versioned Discord install succeeds and config validate passes afterward.

Label justifications:

  • P2: This is a normal-priority CLI/plugin-install regression fix with limited but real impact on Discord onboarding/build recovery.
  • merge-risk: 🚨 compatibility: Merging changes invalid-config recovery behavior by allowing plugins install to remove stale plugin load-path entries for official plugin reinstalls.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes after-fix terminal proof from a local OpenClaw CLI setup with isolated config showing the versioned Discord install succeeds and config validate passes afterward.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal proof from a local OpenClaw CLI setup with isolated config showing the versioned Discord install succeeds and config validate passes afterward.
Evidence reviewed

PR surface:

Source +199, Tests +389. Total +588 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 2 216 17 +199
Tests 2 395 6 +389
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 611 23 +588

What I checked:

  • PR head resolver maps versioned npm specs to official plugin identity: At head fe94a9e, resolveOfficialExternalInstallRecoveryMetadata skips marketplace/file/local specs, parses raw and npm:-prefixed registry specs with parseRegistryNpmSpec, and compares package names against the official catalog npm spec so @openclaw/discord@2026.5.22 can match @openclaw/discord. (src/cli/plugin-install-config-policy.ts:106, fe94a9e68140)
  • Current main did not normalize official versioned specs: Current main only compares raw/normalized install strings and npm: payloads to the catalog npm spec, so a versioned bare spec is not the same identity as the catalog package name. (src/cli/plugin-install-config-policy.ts:105, aefd49909d41)
  • PR head narrows invalid-config cleanup to requested plugin install records: At head fe94a9e, invalid recovery loads persisted install records, accepts missing load-path diagnostics only when they match the requested plugin's install/source path, rejects includes/env-ref cases that could rewrite authored config incorrectly, and then removes only those missing paths. (src/cli/plugins-install-command.ts:718, fe94a9e68140)
  • Regression coverage exercises the intended Discord recovery path: The head tests cover @openclaw/discord@2026.5.22 resolving to Discord recovery metadata, stale load-path removal, persisted install record matching, and rejecting unrelated missing load paths. (src/cli/plugins-install-config.test.ts:170, fe94a9e68140)
  • Linked issue and real proof match the CLI recovery scope: The linked report identifies the build step running openclaw plugins install @openclaw/discord@2026.5.22; the PR body supplies terminal proof that this command succeeds against a stale Discord config and config validate passes afterward. (fe94a9e68140)
  • History points to the existing plugin install recovery surface: git blame ties the current recovery resolver and config loader to commit 333a93ce; git log -S also shows earlier work by Vincent Koc and Peter Steinberger centralizing plugin install config policy and explicit recovery tests. (src/cli/plugins-install-command.ts:493, 333a93ce4486)

Likely related people:

  • vincentkoc: Authored the PR hardening commit and prior current-main test work making plugin install recovery requests explicit. (role: recent area contributor; confidence: high; commits: fe94a9e68140, 30e43550bb91; files: src/cli/plugins-install-command.ts, src/cli/plugin-install-config-policy.ts, src/cli/plugins-install-config.test.ts)
  • steipete: Git history shows Peter Steinberger centralizing plugin install config policy and extracting shared install/persistence command code in this area. (role: feature refactor owner; confidence: medium; commits: fd0fa979526b, 145e514bb55f, 5920ea838d51; files: src/cli/plugin-install-config-policy.ts, src/cli/plugins-install-command.ts, src/cli/plugins-install-persist.ts)
  • lupuletic: Authored the merged Matrix recovery PR that established repair-oriented plugin install flow for stale plugin config. (role: adjacent recovery contributor; confidence: medium; commits: cbb11b366211; files: src/cli/plugins-install-command.ts, src/cli/program/preaction.test.ts, src/commands/doctor/shared/missing-configured-plugin-install.test.ts)
  • zhuisDEV: Authored the merged official plugin install-record pinning work that is related to the persisted install record contract this PR now consults. (role: adjacent install-record contributor; confidence: medium; commits: 7b5f75eb98f4; files: src/plugins/installs.test.ts, src/plugins/update.test.ts, src/commands/doctor/shared/missing-configured-plugin-install.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 14, 2026
@vincentkoc vincentkoc self-assigned this Jun 14, 2026
@openclaw-barnacle openclaw-barnacle Bot added size: L and removed size: S proof: sufficient ClawSweeper judged the real behavior proof convincing. labels Jun 14, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 14, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Maintainer review complete. This is the best fix shape for versioned official-plugin reinstall recovery: recovery stays attributable to the requested plugin and avoids destructive include/env-reference rewrites.

Verification:

  • node scripts/run-vitest.mjs src/cli/plugins-install-config.test.ts src/cli/program/preaction.test.ts (44 tests passed)
  • fresh autoreview: clean, no accepted/actionable findings
  • current PR checks: no failing/pending checks; CodeQL is neutral

Land-ready with no known proof gaps on the touched installer/config recovery surface.

@vincentkoc vincentkoc merged commit a1f18ef into openclaw:main Jun 14, 2026
180 of 184 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 15, 2026
…enclaw-build-messaging-plugins.py exits 1 (openclaw#92869)

* fix(cli): recover versioned Discord plugin installs

* fix(cli): harden plugin install recovery

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
wangmiao0668000666 pushed a commit to wangmiao0668000666/openclaw that referenced this pull request Jun 17, 2026
…enclaw-build-messaging-plugins.py exits 1 (openclaw#92869)

* fix(cli): recover versioned Discord plugin installs

* fix(cli): harden plugin install recovery

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
crh-code pushed a commit to crh-code/openclaw that referenced this pull request Jun 18, 2026
…enclaw-build-messaging-plugins.py exits 1 (openclaw#92869)

* fix(cli): recover versioned Discord plugin installs

* fix(cli): harden plugin install recovery

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
badgerbees pushed a commit to badgerbees/openclaw that referenced this pull request Jul 8, 2026
…enclaw-build-messaging-plugins.py exits 1 (openclaw#92869)

* fix(cli): recover versioned Discord plugin installs

* fix(cli): harden plugin install recovery

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: L status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Discord image build aborts at step 66 — openclaw-build-messaging-plugins.py exits 1

2 participants