On this page

On this page

Gateway

Run doctor

Run openclaw doctor to repair and migrate an OpenClaw install. This page covers the command, its automation flags, and the read-only lint mode.

You can run Doctor after an update without first starting the Gateway. Plugin health checks use the runtime config prepared by Doctor.

Database migrations use the efficient integrity-check default: whole-database quick_check, full checks of tables the migration rewrites or re-indexes, and foreign-key checks. Use openclaw doctor --fix --full-integrity-check to check all tables and indexes during migration. Explicit verification, recovery, and compaction keep their existing checks.

If Doctor cannot verify database readiness because a read-only snapshot did not stabilize, let write activity settle and retry the inspection. Doctor still refuses to complete repair, but snapshot contention alone does not call for a database restore. Integrity failures retain backup-restore guidance for the affected database.

If state storage is not writable, Doctor reports the database or sidecar path that blocked preparation and gives ownership, permission, writable-mount, and immutable-file recovery guidance. It checks effective access rather than treating a different file owner or unsupported chmod as a storage failure. Doctor does not change ownership or clear immutable flags. Fix the reported access problem and rerun Doctor; use openclaw doctor --lint for read-only diagnostics meanwhile.

When the System agent runs Doctor, it uses a separate process from the same OpenClaw installation. Bulk diagnostic checks can then run without blocking the Gateway's event loop. This uses the existing --non-interactive behavior, including its safe migrations; it does not enable additional repairs. Once started, Doctor finishes and releases its resources before a cancelled caller settles, so cancellation cannot abandon an in-progress migration.

Doctor can run while the Gateway owns a current profile: completed daemon runtime-pin migrations do not request offline ownership again. Fresh profiles record this completion during setup or Gateway startup when no legacy pins exist, so their first live Doctor run needs no runtime-pin migration. A pending runtime-pin migration still needs exclusive ownership, including during --non-interactive diagnosis. Stop the Gateway and other state owners for that profile, run openclaw doctor --fix with the same profile/state/config, then restart the Gateway. Doctor preserves the pending migration and reports that next step rather than taking ownership from a live Gateway. Use doctor --lint or doctor --json for read-only diagnostics when offline migrations cannot be completed yet.

Quick start

bash
openclaw doctor

Headless and automation modes

--yes

bash
openclaw doctor --yes

Accept default non-service repairs without prompting and enter maintenance under the service-preservation and installation-drift rules.

--fix

bash
openclaw doctor --fix

Apply recommended non-service repairs without prompting (--repair is an alias) and enter maintenance under the service-preservation and installation-drift rules.

--lint

bash
openclaw doctor --lintopenclaw doctor --lint --json

Run structured health checks for CI or preflight automation. Read-only: no prompts, repairs, migrations, restarts, or state writes.

--fix --force

bash
openclaw doctor --fix --force

Apply aggressive config/state repairs too. Repair maintenance uses the same service-preservation and installation-drift rules; use openclaw gateway install --force from the intended installation to replace its launcher and managed environment.

--non-interactive

bash
openclaw doctor --non-interactive

Run without prompts, applying only safe migrations (config normalization + on-disk state moves). Skips restart/service/sandbox actions that need human confirmation. Legacy state migrations still run automatically when detected. Add --fix for all supported startup-blocking repairs without prompts, including workspace setup, session stores, exec approvals, and audit schema migrations. Explicit repair checks ownership before database snapshots; another live owner must stop before repair can proceed. Malformed or conflicting retained files require the manual recovery named in the error.

When the shared database is already current, preparation leaves the running Gateway's worker environments available. Actual schema repairs retire the old database resources before later maintenance continues, including when repair cleanup fails.

--deep

bash
openclaw doctor --deep

Scan system services for extra gateway installs (launchd/systemd/schtasks).

If a plugin cannot load because its source capture runs out of disk space, Doctor reports ENOSPC with the underlying filesystem error. Free space on the affected filesystem and rerun Doctor. Standalone --non-interactive Doctor exits with code 1; update-invoked Doctor records the problem as a warning so the update can continue while keeping the diagnostic visible.

With OPENCLAW_GATEWAY_STARTUP_TRACE=1, Doctor prints per-phase timings (doctor.* and cli.bootstrap.* lines) to stderr.

To review changes before writing, open the config file first:

bash
cat ~/.openclaw/openclaw.json

Read-only lint mode

openclaw doctor --lint is the automation-friendly sibling of openclaw doctor --fix. They share the same Doctor rule registry, but they do not select or act on rules in the same way:

Mode Prompts Writes config/state Output Use it for
openclaw doctor yes yes, safe migrations and confirmed repairs friendly health report guided checks and repairs
openclaw doctor --json no no JSON advisory report machine-readable operator checks
openclaw doctor --fix sometimes yes, with repair policy friendly repair log applying approved repairs
openclaw doctor --lint no no structured findings CI, preflight, and review gates

Default doctor --lint runs the broad-safe automation profile: checks that are static, local, and useful in CI or preflight output. It skips opt-in checks that are advisory, environment-sensitive, live-service dependent, account/workspace inventory, or historical cleanup. Use doctor --lint --all when you want the full registered lint audit, including those opt-in checks, or --only <id> for a targeted check.

The core/doctor/model-references check also consults the selected Gateway's prepared catalog. Models it publishes do not receive an offline-catalog advisory; server-reported missing models and legacy-reference migrations still do. If the Gateway is unavailable, Doctor keeps its offline checks without discovering or probing providers.

doctor --fix does not use the lint default profile and does not accept --all. It runs Doctor's ordered repair path: modern health checks may provide an optional repair() implementation, and older areas still use their legacy Doctor repair flow. Some lint findings are intentionally diagnostic only, so a check appearing in --lint --all does not mean --fix will mutate that area. The contract separates detect() (reports findings) from repair() (reports changes/diffs/side effects), which keeps a path open for a future doctor --fix --dry-run without turning lint checks into mutation planners.

Some built-in checks are default-disabled internally so they stay available to --all, --only, and Doctor repair flows without becoming part of the default doctor --lint automation profile. Finding severity is still emitted per finding (info, warning, or error); default selection is not a severity level.

bash
openclaw doctor --lintopenclaw doctor --lint --severity-min warningopenclaw doctor --lint --jsonopenclaw doctor --lint --allopenclaw doctor --lint --only core/doctor/gateway-config --json

JSON output fields:

  • schemaVersion: version of the machine-readable lint envelope; branch on this before parsing other fields
  • ok: whether any finding met the selected severity threshold
  • checksRun / checksSkipped: counts (skipped by profile, --only, or --skip)
  • findings: structured diagnostics with checkId, severity, message, and optional path, line, column, ocPath, source, target, requirement, fixHint

Exit codes:

Code Meaning
0 no findings at or above the selected threshold
1 one or more findings met the selected threshold
2 command/runtime failure before findings could be emitted

These threshold-based exit codes belong to explicit --lint mode, with or without --json. Bare openclaw doctor --json preserves ordinary Doctor's advisory exit 0 after producing its payload; machine consumers should read ok and findings. Fatal errors before output remain nonzero.

During openclaw update, failure to remove Doctor's disposable lint snapshot is recorded as an update warning and does not block the update. Standalone doctor --lint still reports that cleanup failure as an error. The update keeps the checks' actual findings; cleanup warnings do not hide other failures.

Flags:

  • --severity-min info|warning|error (default warning): controls both what prints and what causes a non-zero exit.
  • --all: runs every registered lint check, including opt-in checks excluded from the default automation set.
  • --only <id> (repeatable): run only the named check id(s); an unknown id is reported as an error finding.
  • --skip <id> (repeatable): exclude a check while keeping the rest of the run active.
  • --severity-min, --all, --only, and --skip require --lint. Bare --json is allowed for an advisory machine-readable report; --fix rejects it unless another machine mode owns the output.
Was this useful?