2026-07-19
OpenClaw Doctor: Diagnose and Repair Configuration Drift
Use OpenClaw Doctor to capture read-only health findings, choose bounded repairs, validate upgrades and state, and verify the runtime afterward.
OpenClaw Doctor returned ok: false on a Gateway that was running, reachable over RPC, and backed by a schema-valid configuration. That was not a contradiction. The read-only lint found twelve warning records under its security check; the service probe answered normally; and a separate post-upgrade pass ran three plugin-compatibility probes with no findings. Doctor was reporting risk debt, not claiming the process was dead.
This is the distinction that makes OpenClaw Doctor useful. It is not one giant health light. It is a registry of focused checks, migrations, and optional repair functions spread across configuration, secrets, plugins, skills, sessions, supervisors, channels, models, state, and the Gateway runtime. A red automation result only becomes actionable after the operator identifies the check, severity, affected path, and repair owner.
A fresh read-only pass on 23 July 2026 reproduced the boundary rather than merely quoting it. openclaw doctor --lint --json ran 24 checks, skipped 27, returned exit 1, and emitted twelve warnings with stable check IDs. Configuration validation remained true; the managed Gateway stayed active; its service audit and authenticated RPC probe passed; and CLI and Gateway both reported 2026.7.1-2. The separate post-upgrade command ran three plugin probes with no findings. No --fix, --repair, --force, token generation, service rewrite, or state migration was attempted.
Do not pipe doctor --fix --yes into every restart. Repair can rewrite configuration, rotate backups, migrate state, disable unavailable skills, clean plugin references, and interact with service ownership. Detection belongs in automation; mutation belongs in a reviewed change with a narrow target and a verification plan.
A failing lint can coexist with a healthy Gateway
The current machine ran OpenClaw 2026.7.1-2. The baseline command was:
openclaw doctor --lint --json
It ran 24 checks, skipped 27 checks outside the default lint selection, and emitted twelve warning records. Those records came from the security check and described three classes of exposure: secret-bearing configuration stored as plaintext rather than SecretRefs, a network-accessible Gateway bind, and permissive or pairing-oriented Telegram sender policy. There were no error-severity findings in the captured result.
At the same time, openclaw config validate --json returned valid: true. Deep Gateway status showed an active systemd user service, a clean service/config audit, a successful authenticated RPC probe, and matching CLI/server version 2026.7.1-2.
Those observations answer different questions:
- Schema validation asks whether the configuration can be parsed under the current contract.
- Gateway status asks whether the managed service and authenticated control path are working now.
- Doctor lint asks whether selected checks found conditions worth reporting at or above the chosen severity.
A system may pass the first two and fail the third. That should create a remediation record, not an invented outage.
Four numbers before you interpret ok
The lint JSON contains ok, checksRun, checksSkipped, and a findings array. The Boolean is intentionally strict: it becomes false when at least one selected finding meets the severity threshold. It does not encode service availability, blast radius, or whether an automatic repair exists.
| Field | What it proves | Easy misread |
|---|---|---|
ok | No selected finding met the current threshold | “The whole deployment is healthy” |
checksRun | How many registered checks actually executed | “Every Doctor check ran” |
checksSkipped | Checks excluded by profile, filters, or opt-in status | “Skipped means passed” |
checkId | The stable owner for filtering, triage, and allowlisting | Grouping only by message text |
severity | Reported impact class: info, warning, or error | Assuming every non-zero exit is an outage |
path/ocPath | The config, file, or logical object involved when available | Repairing a similarly named but unrelated setting |
Lint exit codes make the same separation. Exit 0 means no finding met the selected threshold. Exit 1 means one or more findings did. Exit 2 means the command failed before it could produce a valid finding set. Automation should preserve all three; collapsing them into success/failure loses the most useful diagnostic distinction.
--severity-min changes both output and exit behavior. A run with --severity-min error may exit zero while lower-severity warnings still exist. Record the flag beside the artifact. Otherwise a green CI badge can be manufactured accidentally by changing the question.
Setup choice: inspection or mutation
Doctor has three main postures, and only one is appropriate for unattended evidence collection.
openclaw doctoris the human-oriented inspection path. It can present guided prompts when a terminal is available.openclaw doctor --lintis always read-only, non-interactive, and designed for stable findings in CI, preflight, and review gates.openclaw doctor --fixor--repairapplies supported repairs. Some service operations still require explicit interaction or a dedicated Gateway command.
--non-interactive is not a synonym for lint. It permits safe migrations and non-service repairs while suppressing prompts. If the requirement is “observe without writes,” use --lint, not a headless repair posture.
There are two other boundaries worth making explicit. --force allows aggressive repair and may overwrite customized service configuration. --allow-exec permits Doctor to execute configured exec SecretRefs while verifying secrets. Neither belongs in a routine read-only baseline.
A green result can mean you asked too little
The default lint set deliberately excludes deep, historical, or opt-in checks. That is why the live result could run 24 and skip 27. Use --all when the complete registered inventory is part of the maintenance window; use --only when a deployment gate should ask one precise question.
# Stable automation baseline
openclaw doctor --lint --json
# One owned check
openclaw doctor --lint \
--only core/doctor/gateway-config \
--json
# Full registered inventory, keeping warnings and errors
openclaw doctor --lint --all \
--severity-min warning \
--json
Always verify checksRun. A mistyped or unavailable selection that runs no useful check should not be accepted as green evidence. Likewise, --skip should be paired with a documented reason and expiry; permanent undocumented skips turn the registry into theater.
For channel permissions, Doctor itself is not the final authority. The official CLI contract points operators to openclaw channels capabilities for a specific target and openclaw channels status --probe for live provider checks. Doctor can identify suspicious configuration, but it cannot replace a provider-specific permission or delivery probe.
Failure modes after an automatic repair
Modern Doctor checks separate detect() from optional repair(). After a successful repair, Doctor re-runs detection against the affected finding. If the finding remains, the command reports a repair warning rather than declaring victory. That is the first proof.
The second proof belongs to the subsystem. A config repair needs a new schema validation and resolved-value check. A service repair needs Gateway status, readiness, and authenticated RPC. A channel repair needs a live provider probe. A plugin repair needs load state plus the workflow that depends on it. A state migration needs integrity evidence and a known rollback point.
Doctor rotates configuration backups when it writes, but a backup file is not a tested rollback. Before mutation, preserve the current artifact, note ownership and permissions, and define the behavior that must recover. Repairs that touch a supervisor owned by another platform should use OPENCLAW_SERVICE_REPAIR_POLICY=external so Doctor can report service health without taking over lifecycle management.
Post-upgrade answers only the plugin question
openclaw doctor --post-upgrade does not repeat the general lint inventory. It runs plugin-compatibility probes intended for a build or update chain. On the reviewed host, JSON mode reported three probes—plugin index availability, unresolved plugin entries, and manifest drift—with an empty findings array.
openclaw doctor --post-upgrade --json
That clean result did not erase the security warnings from --lint. The two commands inspect different surfaces. A useful maintenance record keeps both artifacts: general health/risk findings and post-upgrade plugin compatibility.
Container startup is a special case. A Gateway starting on a new OpenClaw container image performs safe state and plugin repairs before it reports ready. If those repairs cannot finish, startup exits and asks for the same image to run doctor --fix against the mounted config and state. Do not “recover” by running a different image against the same data without first understanding compatibility.
Some findings are policy decisions, not repair tasks
Doctor is broad, but breadth does not make it omniscient. It can report an open sender policy; it cannot decide which human identities the business should trust. It can flag secret-bearing plaintext; it cannot rotate downstream credentials safely without a coordinated secret rollout. It can discover a stopped or mismatched service; it cannot prove an agent completed the user workflow that matters.
That is why the live host result was left unrepaired during evidence collection. The warnings implicated trust and deployment policy. Applying a generic fix would have changed external access and secret ownership without an approved target state. Read-only findings were enough to prioritize the work; they were not authority to mutate it.
A compact Doctor run record should preserve the OpenClaw version, command and filters, timestamp, exit code, checks run/skipped, finding IDs and severities, redacted paths, chosen disposition, any repair diff/effects, repeated detection result, and subsystem canary. Keep the raw artifact private because it can reveal configuration paths, plugin names, channel posture, and other useful reconnaissance.
The decision this host actually supports
The 23 July evidence supports a narrow decision. The Gateway was operational, configuration parsing and RPC health were green, general lint remained non-green because twelve selected warnings met the threshold, and all three post-upgrade plugin probes were clean. “Restart until Doctor turns green” would act on the healthy layer. The defensible next move is to assign each security finding an owner, choose the intended secret and network boundary, apply one reviewed change, then repeat the affected lint and its runtime canary.
This is the core Doctor discipline: detect broadly, repair narrowly, verify in the owning subsystem. A command that reports more than one layer must not tempt operators into treating every layer as the same failure.
If your team would rather consume a managed agent runtime than own configuration migrations, service supervisors, plugin compatibility, secret posture, and channel recovery on every host, deploy an AI agent on GolemWorkers. The related OpenClaw security audit, Gateway operating guide, and update handoff note cover the subsystems Doctor points toward.
Sources retained with this decision
- OpenClaw Doctor CLI reference — postures, flags, lint fields, exit codes, check selection, repair verification, post-upgrade probes, and operating notes.
- OpenClaw Gateway Doctor guide — detailed check ownership, migrations, service behavior, state integrity, and repair boundaries.
- OpenClaw Gateway troubleshooting — subsystem-specific diagnosis after a Doctor finding.
- OpenClaw Gateway security — secret, ingress, sender-policy, and trust-boundary interpretation.