openclaw - ✅(Solved) Fix doctor --fix fails atomically when config has multiple validation errors, preventing fixes from persisting [1 pull requests, 2 comments, 3 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#77802Fetched 2026-05-06 06:21:11
View on GitHub
Comments
2
Participants
3
Timeline
4
Reactions
2
Author
Timeline (top)
commented ×2cross-referenced ×2

Error Message

After upgrading OpenClaw, running openclaw doctor --fix enters a broken loop where no fixes can persist because the tool fails atomically on any validation error.

  • Finally it crashes with exit code 1 due to an unrelated validation error:

Error: Config validation failed: models.providers.bailian.models.0.compat.thinkingFormat: Invalid input (allowed: "openai", "openrouter", "deepseek", "zai")

  1. Apply all possible fixes and save them incrementally, so that fixing one issue isn't blocked by another unrelated validation error.

Root Cause

After upgrading OpenClaw, running openclaw doctor --fix enters a broken loop where no fixes can persist because the tool fails atomically on any validation error.

Fix Action

Fixed

PR fix notes

PR #77876: fix(doctor): exit non-zero on final invalid config (#77804)

Description (problem / solution / changelog)

Summary

openclaw doctor prints Invalid config: … when the final config validation step finds problems, but the process still exits 0, falsely reassuring CI/CD pipelines and wrapper scripts that the config is healthy. Issue #77804 reports the exact mix of "Doctor complete." (success framing) followed by Invalid config: … returning $LASTEXITCODE = 0 on Windows PowerShell, but the same path is taken on every platform.

The bug is two-step:

  1. runFinalConfigValidationHealth in src/flows/doctor-health-contributions.ts detected the invalid snapshot but never set process.exitCode.
  2. The doctor action in src/cli/program/register.maintenance.ts hardcoded defaultRuntime.exit(0) after doctorCommand returned, which would have overridden any process.exitCode set inside the flow anyway.

This PR fixes both halves:

  • runFinalConfigValidationHealth now sets process.exitCode = 1 after emitting the Invalid config: lines, only when the current process.exitCode is falsy (so it does not lower a non-zero code already set earlier in the run).
  • The doctor registration now exits via defaultRuntime.exit(process.exitCode ?? 0) instead of defaultRuntime.exit(0), so the signal from the flow is honored. All other surrounding behavior is unchanged.

outro("Doctor complete.") wording is preserved per AGENTS.md additive philosophy. No new flag, no new option, no behavior change for valid configs. Companion issue #77802 (doctor --fix atomicity / last-known-good auto-restore) is intentionally out of scope here — that touches recovery-policy.ts and is a separate design call; I commented on the issue to surface that.

Real behavior proof

  • Behavior or issue addressed: openclaw doctor exits 0 even though it printed Invalid config: … at the end of the run, masking unhealthy configs from CI/CD and wrapper scripts. Tracked in #77804.

  • Real environment tested: macOS Darwin 25.4.0 / Node v25.9.0 (arm64) on a real openclaw checkout, running the full node openclaw.mjs doctor launcher against a real ~/.openclaw-77804repro/openclaw.json written to disk with an invalid bailian provider shape.

  • Exact steps or command run after this patch:

    mkdir -p ~/.openclaw-77804repro
    cat > ~/.openclaw-77804repro/openclaw.json <<'JSON'
    { "models": { "providers": { "bailian": { "models": { "qwen-plus": { "compat": { "thinkingFormat": "not-a-real-format" } } } } } } }
    JSON
    node openclaw.mjs --profile 77804repro --no-color doctor --non-interactive --no-workspace-suggestions
    echo "EXIT=$?"
  • Evidence after fix: live runtime stdout captured before and after the patch was applied to the same launcher and same on-disk config.

    Before the patch — exit 0, masking the failure:

    Run "openclaw --profile 77804repro doctor --fix" to apply changes.
    Invalid config:
    - models.providers.bailian.baseUrl: Invalid input: expected string, received undefined
    - models.providers.bailian.models: Invalid input: expected array, received object
    └  Doctor complete.
    EXIT=0

    After the patch — same Invalid config: block, but exit 1:

    Run "openclaw --profile 77804repro doctor --fix" to apply changes.
    Invalid config:
    - models.providers.bailian.baseUrl: Invalid input: expected string, received undefined
    - models.providers.bailian.models: Invalid input: expected array, received object
    └  Doctor complete.
    EXIT=1
  • Observed result after fix: node openclaw.mjs doctor against a real openclaw.json that fails final validation now terminates with shell exit code 1 while preserving the existing user-facing output, including the "Doctor complete." closing line. CI/CD pipelines and shell wrappers that branch on the exit code (if openclaw doctor; then …) will now see the failure they previously missed.

  • What was not tested: No Windows PowerShell live run was performed locally — the issue reporter is on PowerShell on Windows 10. The fix path is platform-agnostic (process.exitCode semantics are identical across Node-supported OSes), and the policy is exercised by Vitest, but a Windows live run was not feasible in this environment.

Fixes #77804.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/cli/program/register.maintenance.test.ts (modified, +19/-1)
  • src/cli/program/register.maintenance.ts (modified, +1/-1)
  • src/flows/doctor-health-contributions.test.ts (modified, +91/-1)
  • src/flows/doctor-health-contributions.ts (modified, +3/-0)
RAW_BUFFERClick to expand / collapse

Bug Description

After upgrading OpenClaw, running openclaw doctor --fix enters a broken loop where no fixes can persist because the tool fails atomically on any validation error.

Reproduction Steps

  1. Have a config with multiple issues, e.g.:
    • plugins.deny references a non-existent plugin (openclaw-weixin)
    • models.providers.bailian.models.*.compat.thinkingFormat has invalid enum values
    • stale plugins.allow / plugins.entries references (acpx)
  2. Run openclaw doctor — it reports all issues and says Run "openclaw doctor --fix" to apply changes.
  3. Run openclaw doctor --fix

Observed Behavior

  • --fix starts by auto-restoring config from last-known-good because the current config is invalid:

    Config auto-restored from last-known-good: ...openclaw.json (doctor-invalid-config); Rejected validation details: plugins.deny: plugin not found: openclaw-weixin; ...

  • It then claims to apply fixes:
    • Set plugins.bundledDiscovery="compat"
    • Installed missing configured plugin "feishu"
    • plugins.allow: removed 1 stale plugin id (acpx)
    • plugins.entries: removed 1 stale plugin entry (acpx)
  • Finally it crashes with exit code 1 due to an unrelated validation error:

    Error: Config validation failed: models.providers.bailian.models.0.compat.thinkingFormat: Invalid input (allowed: "openai", "openrouter", "deepseek", "zai")

  • Run openclaw doctor again — the stale acpx references are back, and all prompts to run --fix reappear.

Expected Behavior

doctor --fix should:

  1. Either not auto-restore last-known-good when the user explicitly asked to fix the current config, OR
  2. Apply all possible fixes and save them incrementally, so that fixing one issue isn't blocked by another unrelated validation error.

Environment

  • OS: Windows 10 Education 10.0.19045
  • Shell: PowerShell
  • OpenClaw: just upgraded to latest

Impact

This makes doctor --fix effectively unusable for real-world configs that accumulate multiple issues across upgrades. Users are forced to manually edit openclaw.json instead of using the automated repair tool.

extent analysis

TL;DR

The openclaw doctor --fix command enters a broken loop due to validation errors, and a potential fix is to modify the command to apply fixes incrementally or not auto-restore the last-known-good config.

Guidance

  • The issue seems to be caused by the openclaw doctor --fix command's inability to handle multiple validation errors, so a possible solution is to modify the command to apply fixes one by one.
  • To verify the issue, try running openclaw doctor --fix with a config that has multiple issues and check if the command crashes with an unrelated validation error.
  • To mitigate the issue, users can manually edit the openclaw.json file to fix the validation errors one by one, or try to modify the openclaw doctor --fix command to apply fixes incrementally.
  • Another possible solution is to modify the command to not auto-restore the last-known-good config when the user explicitly asks to fix the current config.

Example

No code snippet is provided as the issue does not imply a specific code change.

Notes

The issue seems to be specific to the openclaw doctor --fix command and its handling of validation errors. The solution may require modifying the command's behavior or adding additional error handling.

Recommendation

Apply workaround: manually edit the openclaw.json file to fix the validation errors one by one, as the openclaw doctor --fix command is currently unusable for real-world configs with multiple issues.

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