openclaw - ✅(Solved) Fix Chicken-and-egg: `openclaw doctor --fix` cannot repair missing staged runtime deps because config loading itself fails [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#70521Fetched 2026-04-24 05:57:00
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×2referenced ×2closed ×1commented ×1

After upgrading OpenClaw (e.g. 2026.4.12 → 2026.4.21), bundled plugin staged runtime dependencies (such as @larksuiteoapi/node-sdk for the feishu plugin) may be missing. Running openclaw doctor --fix should repair this, but instead fails with Cannot find module '@larksuiteoapi/node-sdk' during config loading — a chicken-and-egg problem.

Error Message

Config invalid; doctor will run with best-effort config.

Failed to read config at ~/.openclaw/openclaw.json Error: Cannot find module '@larksuiteoapi/node-sdk'

Invalid config:

  • <root>: read failed: Error: Cannot find module '@larksuiteoapi/node-sdk'

Root Cause

In src/flows/doctor-health.ts, the execution order is:

  1. loadAndMaybeMigrateDoctorConfig()crashes here due to plugin source loading requiring the missing dep
  2. runDoctorHealthContributions() ← never reached; this is where maybeRepairBundledPluginRuntimeDeps lives

The repair function scanBundledPluginRuntimeDeps only needs the package root and reads package.json files — it does NOT depend on config. But it runs after config loading, which may fail due to the missing deps.

The same issue affects gateway daemon startup: if the dep is missing, the gateway crashes before any repair can happen.

Fix Action

Fixed

PR fix notes

PR #70536: fix(runtime-deps): repair bundled deps before startup (#70521)

Description (problem / solution / changelog)

Summary

  • Problem: openclaw doctor --fix and gateway startup could both fail before bundled plugin runtime deps were repaired, so a missing staged dep like @larksuiteoapi/node-sdk could brick the recovery path.
  • Why it matters: once config loading touches a bundled plugin that needs a missing staged dep, the process fails before the existing repair logic gets a chance to run.
  • What changed: added a bundled-runtime-deps preflight before doctor config loading, and added the same kind of preflight before gateway startup maintenance/plugin bootstrap.
  • What did NOT change (scope boundary): this does not change how bundled runtime deps are scanned or installed, and it does not add any new config knobs.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #70521
  • Related #70339
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: the repair path for staged bundled runtime deps ran after doctor config loading and after gateway startup had already moved into plugin/bootstrap work, so missing deps could break startup before repair was attempted.
  • Missing detection / guardrail: there was no regression coverage locking in "repair missing bundled runtime deps before config/bootstrap touches configured channel modules."
  • Contributing context (if known): this shows up after upgrades where bundled staged deps are missing but the config still enables the affected channel.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/flows/doctor-health.test.ts, src/gateway/server-startup-plugins.test.ts
  • Scenario the test should lock in: doctor and gateway startup both repair missing bundled runtime deps before config loading or startup maintenance proceeds.
  • Why this is the smallest reliable guardrail: the bug is about call ordering, and these tests pin that ordering directly without needing a full upgrade/install harness.
  • Existing test that already covers this (if any): None.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

openclaw doctor --fix can now repair missing bundled plugin runtime deps before config loading trips over them, and normal gateway startup gets the same preflight repair path.

Diagram (if applicable)

Before:
doctor/gateway startup -> config/plugin load touches missing dep -> crash before repair

After:
doctor/gateway startup -> bundled runtime deps preflight -> missing dep installed -> config/plugin load continues

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (Yes)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation: gateway startup now reuses the existing bundled runtime dep installer earlier in startup, but only after the scan finds missing staged deps for configured channels. The installer path and package-root detection are unchanged.

Repro + Verification

Environment

  • OS: macOS (local focused validation)
  • Runtime/container: repo unit-fast Vitest harness
  • Model/provider: N/A
  • Integration/channel (if any): bundled channel deps, including the feishu-style staged runtime dep case from the report
  • Relevant config (redacted): configured channel with bundled staged runtime deps enabled

Steps

  1. Start from a config that enables a bundled channel whose staged runtime dep is missing after upgrade.
  2. Run openclaw doctor --fix, or start the gateway.
  3. Observe whether repair runs before config/plugin startup reaches the missing module.

Expected

  • Repair runs first, installs any missing bundled staged runtime deps, then doctor/gateway continues.

Actual

  • Before this patch, config/plugin loading could fail first with Cannot find module ..., so the repair path never ran.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Focused validation:

  • OPENCLAW_VITEST_INCLUDE_FILE=/tmp/openclaw-70521-vitest-include.json pnpm exec vitest run --config test/vitest/vitest.unit-fast.config.ts
  • Passed:
    • src/flows/doctor-health.test.ts
    • src/gateway/server-startup-plugins.test.ts

Issue evidence:

  • Reported failure during doctor config loading: Cannot find module '@larksuiteoapi/node-sdk'

Human Verification (required)

  • Verified scenarios: confirmed both doctor flow and gateway startup run the bundled-runtime-deps repair path before the later config/bootstrap steps touched by the issue.
  • Edge cases checked: no-op when package root is unavailable, no-op when nothing is missing, warning path when version conflicts are detected, and minimal-test gateway mode still skips the startup preflight.
  • What you did not verify: I did not run a full global-upgrade repro with a real missing feishu install, and I did not run the full repo test suite in this environment.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: gateway startup may spend extra time on the preflight when bundled deps are actually missing.
    • Mitigation: the scan runs first and the install path is only taken when missing deps are detected.
  • Risk: conflicting bundled dep versions are still a messy startup state.
    • Mitigation: the preflight warns on conflicts and otherwise leaves the existing install logic untouched.

Changed files

  • src/flows/doctor-health.test.ts (added, +122/-0)
  • src/flows/doctor-health.ts (modified, +13/-0)
  • src/gateway/server-startup-plugins.test.ts (added, +307/-0)
  • src/gateway/server-startup-plugins.ts (modified, +81/-0)
  • src/plugins/contracts/plugin-sdk-package-contract-guardrails.test.ts (modified, +1/-0)

PR #70539: fix(doctor): preflight bundled runtime dep repair before config loading

Description (problem / solution / changelog)

Summary

  • Add a preflight step to install missing bundled plugin runtime deps before config loading in openclaw doctor
  • Fixes a chicken-and-egg bug where openclaw doctor --fix cannot repair missing deps because config loading crashes first

Problem

After upgrading OpenClaw (e.g. 2026.4.12 → 2026.4.21), bundled plugin staged runtime dependencies such as @larksuiteoapi/node-sdk (feishu plugin) may be missing. The existing repair runs inside loadAndMaybeMigrateDoctorConfig, but config loading itself triggers plugin source code via jiti (e.g. feishu/client.jsimport * as Lark from "@larksuiteoapi/node-sdk"), which throws MODULE_NOT_FOUND before the repair is ever reached.

Result: openclaw doctor --fix prints "Config invalid; doctor will run with best-effort config" and never installs the missing deps.

Fix

Move maybeRepairBundledPluginRuntimeDeps to a preflight step in doctorCommand() that runs before loadAndMaybeMigrateDoctorConfig(). The repair function (scanBundledPluginRuntimeDeps) only needs the package root and reads package.json files from the filesystem — it does not depend on config, making it safe to run early.

The existing health contribution (doctor:bundled-plugin-runtime-deps) and the call inside loadAndMaybeMigrateDoctorConfig remain in place for config-aware checks (e.g. includeConfiguredChannels).

Testing

  • Existing e2e test harness already mocks maybeRepairBundledPluginRuntimeDeps and will validate the call pattern
  • Manual verification: after removing @larksuiteoapi/node-sdk, openclaw doctor --fix now installs it before attempting config loading

Closes: #70521

Changed files

  • src/flows/doctor-health.ts (modified, +13/-0)

Code Example

Config invalid; doctor will run with best-effort config.

Failed to read config at ~/.openclaw/openclaw.json
Error: Cannot find module '@larksuiteoapi/node-sdk'

Invalid config:
- <root>: read failed: Error: Cannot find module '@larksuiteoapi/node-sdk'
RAW_BUFFERClick to expand / collapse

Summary

After upgrading OpenClaw (e.g. 2026.4.12 → 2026.4.21), bundled plugin staged runtime dependencies (such as @larksuiteoapi/node-sdk for the feishu plugin) may be missing. Running openclaw doctor --fix should repair this, but instead fails with Cannot find module '@larksuiteoapi/node-sdk' during config loading — a chicken-and-egg problem.

Steps to Reproduce

  1. Have OpenClaw 2026.4.12 installed with feishu channel enabled
  2. Upgrade: pnpm update -g openclaw (to 2026.4.21)
  3. Run openclaw doctor --fix

Expected Behavior

openclaw doctor --fix detects and installs the missing staged runtime deps, then proceeds normally.

Actual Behavior

Config invalid; doctor will run with best-effort config.

Failed to read config at ~/.openclaw/openclaw.json
Error: Cannot find module '@larksuiteoapi/node-sdk'

Invalid config:
- <root>: read failed: Error: Cannot find module '@larksuiteoapi/node-sdk'

The --fix flag cannot repair because config loading crashes before the repair health contribution (doctor:bundled-plugin-runtime-deps) ever runs.

Root Cause

In src/flows/doctor-health.ts, the execution order is:

  1. loadAndMaybeMigrateDoctorConfig()crashes here due to plugin source loading requiring the missing dep
  2. runDoctorHealthContributions() ← never reached; this is where maybeRepairBundledPluginRuntimeDeps lives

The repair function scanBundledPluginRuntimeDeps only needs the package root and reads package.json files — it does NOT depend on config. But it runs after config loading, which may fail due to the missing deps.

The same issue affects gateway daemon startup: if the dep is missing, the gateway crashes before any repair can happen.

Suggested Fix

Move the bundled runtime dep repair to a preflight step that runs before config loading in both the doctor flow and gateway startup:

  1. Doctor flow (src/flows/doctor-health.ts): call maybeRepairBundledPluginRuntimeDeps before loadAndMaybeMigrateDoctorConfig
  2. Gateway startup (src/gateway/server.impl.ts): add a preflight check before loadGatewayStartupPlugins

This ensures missing deps are installed before any code path that might require them.

Environment

  • OpenClaw: 2026.4.21
  • Previous version: 2026.4.12
  • Package manager: pnpm (global)
  • Affected plugins: feishu (uses @larksuiteoapi/node-sdk), potentially others with stageRuntimeDependencies: true

extent analysis

TL;DR

Move the bundled runtime dependency repair to a preflight step that runs before config loading in both the doctor flow and gateway startup.

Guidance

  • Identify the execution order in src/flows/doctor-health.ts and src/gateway/server.impl.ts to confirm the current flow.
  • Consider moving the maybeRepairBundledPluginRuntimeDeps function to a preflight step before loadAndMaybeMigrateDoctorConfig in the doctor flow.
  • Add a preflight check before loadGatewayStartupPlugins in the gateway startup to ensure missing dependencies are installed before loading plugins.
  • Verify that the scanBundledPluginRuntimeDeps function only requires the package root and reads package.json files, and does not depend on config loading.

Example

No code snippet is provided as the issue does not require a specific code change, but rather a reordering of existing functions.

Notes

This solution assumes that moving the bundled runtime dependency repair to a preflight step will resolve the issue. However, additional testing and verification may be necessary to ensure that this change does not introduce new issues.

Recommendation

Apply the suggested fix by moving the bundled runtime dependency repair to a preflight step, as this should resolve the chicken-and-egg problem and allow the openclaw doctor --fix command to complete successfully.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix Chicken-and-egg: `openclaw doctor --fix` cannot repair missing staged runtime deps because config loading itself fails [2 pull requests, 1 comments, 2 participants]