fix(channels): hint at when bundled channel module is missing#76974
Conversation
|
Codex review: passed. Workflow note: Future ClawSweeper reviews update this same comment in place. How this review workflow works
Summary Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare PR rating What the crustacean ranks mean
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. Real behavior proof Risk before merge
Maintainer options:
Next step before merge Security Review detailsBest possible solution: Land the focused formatter and tests after normal CI, preserving doctor-owned staged dependency repair instead of adding plugin runtime dependencies to the root package. Do we have a high-confidence way to reproduce the issue? Yes, source-level: current main logs bundled-channel load failures with bare Is this the best way to solve the issue? Yes: a central formatter reused by all bundled-channel warning sites is the narrow maintainable fix and avoids the rejected root-dependency workaround. The deeper Feishu disable/runtime-dependency issue remains outside this PR's scope. Label changes:
Label justifications:
What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 8961eae3f022. |
b33226d to
947fa96
Compare
Native-require failures in module-loader.ts wrap the original Node error
in a new Error with { cause }, so MODULE_NOT_FOUND lives on the cause
rather than the top-level error. extractErrorCode only inspected the
top-level code, so packaged bundled-channel load failures missed the new
hint.
Walk the .cause chain (with cycle protection) when classifying bundled
channel load errors, and add focused tests pinning the warning text for
top-level MODULE_NOT_FOUND, top-level ERR_MODULE_NOT_FOUND, nested-cause
MODULE_NOT_FOUND, unrelated errors, and self-referential cause chains.
Addresses clawsweeper review feedback on openclaw#76974.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
003206c to
25fb6c7
Compare
|
Addressed @clawsweeper P2 in 25fb6c7:
Local: Also rebased onto current |
|
For the maintainer triaging this PR: there is now a user-reported issue #78321 (filed yesterday by @makingperfectmoves-oss) that describes the exact symptom this PR addresses — recurring To be precise: this PR does not fix the deeper architectural issues raised in #78321 (early Happy to update the PR description / changelog wording to call out the relation explicitly if that helps triage. |
Comment for PR #76974 — fix(channels): hint at
|
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
…odule is missing When a bundled channel plugin (e.g. `nostr`, `whatsapp`, `msteams`) fails to load because its plugin-local runtime dependency is not yet staged, the loader emitted a bare `Cannot find module 'X'` warning with no remediation hint. The intended repair path is `openclaw doctor --fix` (per openclaw#48803), so users were left to discover this themselves. Detect `ERR_MODULE_NOT_FOUND` / `MODULE_NOT_FOUND` in the bundled channel load error path and append the canonical `run \`openclaw doctor --fix\` to install missing bundled runtime dependencies for channel <id>` guidance to the warning detail. Applied at all seven `[channels] failed to load bundled channel ...` warn sites in `bundled.ts`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit 17e6794)
Native-require failures in module-loader.ts wrap the original Node error
in a new Error with { cause }, so MODULE_NOT_FOUND lives on the cause
rather than the top-level error. extractErrorCode only inspected the
top-level code, so packaged bundled-channel load failures missed the new
hint.
Walk the .cause chain (with cycle protection) when classifying bundled
channel load errors, and add focused tests pinning the warning text for
top-level MODULE_NOT_FOUND, top-level ERR_MODULE_NOT_FOUND, nested-cause
MODULE_NOT_FOUND, unrelated errors, and self-referential cause chains.
Addresses clawsweeper review feedback on openclaw#76974.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Re-place CHANGELOG entry under the current Unreleased > Fixes section after rebase onto main (previous placement targeted a stale section). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
0173a59 to
810f51a
Compare
…oad-doctor-hint # Conflicts: # CHANGELOG.md
|
Rebased onto current GitHub now reports @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Follow-up: after-fix real behavior proof (addresses ClawSweeper rank-up move) Same wrapped-error reproduction as the earlier comment, now running the PR's new node --input-type=module -e "
import { createRequire } from 'node:module';
const req = createRequire(import.meta.url);
const formatErrorMessage = e => e instanceof Error ? e.message : String(e);
// Native-require wrap exactly as src/channels/plugins/module-loader.ts does it.
function buildWrappedNostrError() {
try { req('nostr-tools'); }
catch (cause) { return new Error('failed to load channel plugin module with native require: nostr-tools', { cause }); }
}
// BEFORE: the current 2026.5.12 path used at all seven warn sites.
const describeBefore = err => formatErrorMessage(err);
// AFTER: this PR's describeBundledChannelLoadError + findMissingModuleCodeInChain.
function describeAfter(error, channelId) {
const detail = formatErrorMessage(error);
const seen = new Set();
let cur = error;
while (cur && !seen.has(cur)) {
seen.add(cur);
const code = (cur && typeof cur === 'object' && 'code' in cur) ? cur.code : undefined;
if (code === 'MODULE_NOT_FOUND' || code === 'ERR_MODULE_NOT_FOUND') {
return detail + ' (run \`openclaw doctor --fix\` to install missing bundled runtime dependencies for channel ' + channelId + ')';
}
if (typeof cur !== 'object') break;
cur = cur.cause;
}
return detail;
}
const err = buildWrappedNostrError();
console.log('cause.code on inner error:', err && err.cause && err.cause.code);
console.log('');
console.log('BEFORE WARN [channels] failed to load bundled channel nostr: ' + describeBefore(err));
console.log('AFTER WARN [channels] failed to load bundled channel nostr: ' + describeAfter(err, 'nostr'));
console.log('');
// Negative case: a non-missing-module failure must NOT get the hint.
const generic = new Error('outer', { cause: new TypeError('something else') });
console.log('Edge: non-missing-module error, should NOT add hint:');
console.log('AFTER WARN [channels] failed to load bundled channel nostr: ' + describeAfter(generic, 'nostr'));
"Output on a clean Ubuntu 24.04 / Node 22.22.0 host where So with the PR applied the warn site emits the Current HEAD: @clawsweeper re-review |
|
🦞🧹 Reason: re-review requires an open issue or PR. Re-review progress:
|
|
Follow-up: PR-built proof via direct import + vitest on branch HEAD Addresses the rank-up move "Attach redacted terminal or log output from a PR-built helper import, package, or gateway path showing the bundled-channel warning includes the 1)
|
|
@clawsweeper automerge |
|
🦞✅ Source: What merged:
Automerge notes:
The automerge loop is complete. Automerge progress:
|
|
🦞✅ Source: Why human review is needed: Recommended next action: I added |
|
ClawSweeper PR egg ✨ Hatched: 🌱 uncommon Clockwork Patch Peep Hatch commandComment Hatchability rules:
Rarity: 🌱 uncommon. What is this egg doing here?
|
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…aw#76974) Summary: - The PR adds a bundled-channel load-error formatter, wires it into the bundled-channel warning paths, adds focused tests, and updates the changelog. - Reproducibility: yes. source-level: current main logs bundled-channel load failures with bare `formatErrorMe ... cause`. The contributor's terminal proof demonstrates the same wrapped-error shape before and after the PR. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(channels): walk error cause chain to detect missing bundled modules - PR branch already contained follow-up commit before automerge: docs(changelog): add Unreleased Fixes entry - PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/bundled-channel-l… - PR branch already contained follow-up commit before automerge: Merge branch 'main' into fix/bundled-channel-load-doctor-hint Validation: - ClawSweeper review passed for head 416a8a2. - Required merge gates passed before the squash merge. Prepared head SHA: 416a8a2 Review: openclaw#76974 (comment) Co-authored-by: BSG2000 <github@hsu.hamburg> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: BSG2000 <BSG2000@users.noreply.github.com> Co-authored-by: BSG2000 <thomas.krohnfuss@stud.th-luebeck.de> Co-authored-by: Thomas Krohnfuß <BSG2000@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary
When a bundled channel plugin (e.g.
nostr,discord,whatsapp,msteams) fails to load because its plugin-local runtime dependency hasn't been staged yet, the loader currently emits a bare warning like:This is alarming and not actionable — users have no signal that the supported repair path is
openclaw doctor --fix, which is the design @steipete confirmed when closing #48803 ("doctor owns the repair path").This PR detects
ERR_MODULE_NOT_FOUND/MODULE_NOT_FOUNDon the bundled channel load path and appends the canonical guidance to the warning detail, e.g.:The hint phrasing matches existing usages in
src/plugins/discovery.ts,src/plugins/plugin-registry-snapshot.ts, andsrc/cli/plugins-install-command.tsso users see a consistent remediation surface.Why this approach
package.json(which fix: add nostr-tools to root dependencies #48803 explicitly rejected); just makes the existing per-plugin staging design discoverable when it hasn't run yet.[channels] failed to load bundled channel ...warn sites inbundled.ts(entry, setup entry, plugin, secrets, account inspector, setup plugin, setup secrets), so any of them produces the same friendly hint.Reproduction
npm install -g openclaw@2026.5.2 && openclaw gateway restarton a host that hasn't yet hadopenclaw doctor --fixstage the nostr plugin's runtime deps reproduces the warning.Tests
pnpm exec vitest run --config test/vitest/vitest.channels.config.ts src/channels/plugins/bundled-root-caches.test.ts— 4 passed (existing tests cover the load-error path mocked withCannot find module 'nostr-tools'; my change only enriches the warning string and does not alter control flow).src//packages/, so no test updates were required.Risk
Very low — appending to a warning string. No new exports, no public API, no control-flow changes. If
extractErrorCodereturns anything other thanERR_MODULE_NOT_FOUND/MODULE_NOT_FOUNDthe originalformatErrorMessage(error)output is returned unchanged.Changelog
Added under
## Unreleased > ### Fixesper repo convention.🤖 Drafted with assistance from GitHub Copilot CLI.