# Doctor

> Doctor 命令：健康检查、配置迁移和修复步骤

- 网址：https://funcoding.ai/agents/openclaw/gateway/doctor/
- 来源：OpenClaw 官方文档原文（中文），MIT 许可，同步于 2026-10-11
- 官方原文：https://docs.openclaw.ai/zh-CN/gateway/doctor

---
`openclaw doctor` 是 OpenClaw 的修复和迁移工具。它可修复过时的配置/状态、检查健康状况，并提供可执行的修复步骤。

## 快速开始

```bash
openclaw doctor
```

### 无头和自动化模式

**--yes**

```bash
openclaw doctor --yes
```

无需提示即接受默认选项（适用时包括重启/服务/沙箱修复步骤）。

**--fix**

```bash
openclaw doctor --fix
```

无需提示即应用建议的修复（`--repair` 是其别名）。

**--lint**

```bash
openclaw doctor --lint
openclaw doctor --lint --json
```

为 CI 或预检自动化运行结构化健康检查。只读：不会进行
提示、修复、迁移、重启或状态写入。

**--fix --force**

```bash
openclaw doctor --fix --force
```

同时应用激进修复（会覆盖自定义监督器配置）。

**--non-interactive**

```bash
openclaw doctor --non-interactive
```

无提示运行，仅应用安全迁移（配置规范化 +
磁盘状态移动）。跳过需要人工
确认的重启/服务/沙箱操作。检测到旧版状态迁移时，仍会自动执行。

**--deep**

```bash
openclaw doctor --deep
```

扫描系统服务以查找额外安装的 Gateway 网关（launchd/systemd/schtasks）。

若要在写入前审查更改，请先打开配置文件：

```bash
cat ~/.openclaw/openclaw.json
```

## 只读 lint 模式

`openclaw doctor --lint` 是 `openclaw doctor --fix` 面向自动化的同类模式。两者共享同一个 Doctor 规则注册表，但选择和执行规则的方式
并不相同：

| 模式                     | 提示   | 写入配置/状态     | 输出                 | 用途                      |
| ------------------------ | --------- | ----------------------- | ---------------------- | ------------------------------- |
| `openclaw doctor`        | 是       | 否                      | 易读的健康报告 | 人工检查状态         |
| `openclaw doctor --fix`  | 有时 | 是，遵循修复策略 | 易读的修复日志    | 应用已批准的修复       |
| `openclaw doctor --lint` | 否        | 否                      | 结构化发现    | CI、预检和审查门禁 |

默认的 `doctor --lint` 会运行广泛且安全的自动化配置：检查静态、本地且适用于 CI 或预检输出的项目。它会跳过需要选择启用的检查，包括建议性检查、易受环境影响的检查、依赖实时服务的检查、账户/工作区清单检查或历史清理检查。如果需要完整的已注册 lint 审计（包括这些选择启用的检查），请使用 `doctor --lint --all`；如需执行目标检查，请使用 `--only <id>`。

`doctor --fix` 不使用 lint 默认配置，也不接受
`--all`。它会运行 Doctor 的有序修复路径：现代健康检查可以提供可选的 `repair()` 实现，而较旧的区域仍使用其旧版
Doctor 修复流程。部分 lint 发现有意仅用于诊断，因此某项检查出现在 `--lint --all` 中，并不意味着 `--fix` 会修改该区域。
此契约将 `detect()`（报告发现）与 `repair()`（报告
更改/差异/副作用）分离，从而为未来的
`doctor --fix --dry-run` 留出实现空间，而无需将 lint 检查转变为修改规划器。

部分内置检查在内部默认禁用，以便它们仍可用于
`--all`、`--only` 和 Doctor 修复流程，同时不会成为默认
`doctor --lint` 自动化配置的一部分。仍会为每项发现输出其严重级别（`info`、`warning` 或 `error`）；默认选择并不是严重级别。

```bash
openclaw doctor --lint
openclaw doctor --lint --severity-min warning
openclaw doctor --lint --json
openclaw doctor --lint --all
openclaw doctor --lint --only core/doctor/gateway-config --json
```

JSON 输出字段：

- `ok`：是否有任何发现达到所选严重级别阈值
- `checksRun` / `checksSkipped`：计数（因配置、`--only` 或 `--skip` 而跳过）
- `findings`：包含 `checkId`、`severity`、`message`，以及可选的 `path`、`line`、`column`、`ocPath`、`source`、`target`、`requirement`、`fixHint` 的结构化诊断

退出代码：

| 代码 | 含义                                                  |
| ---- | -------------------------------------------------------- |
| `0`  | 没有发现达到或超过所选阈值           |
| `1`  | 一项或多项发现达到所选阈值          |
| `2`  | 在能够输出发现之前发生命令/运行时故障 |

标志：

- `--severity-min info|warning|error`（默认值为 `warning`）：同时控制输出内容以及导致非零退出的条件。
- `--all`：运行所有已注册的 lint 检查，包括默认自动化集合中排除的选择启用检查。
- `--only <id>`（可重复）：仅运行指定检查 ID；未知 ID 将报告为错误发现。
- `--skip <id>`（可重复）：排除某项检查，同时继续运行其余检查。
- `--json`、`--severity-min`、`--all`、`--only` 和 `--skip` 需要 `--lint`；普通的 `openclaw doctor` 和 `--fix` 运行会拒绝这些标志。

## 功能摘要

<details>
<summary>健康状况、UI 和更新</summary>

- 针对 git 安装的可选预检更新（仅交互模式）。
- UI 协议时效性检查（当协议架构较新时重新构建 Control UI）。
- 健康检查 + 重启提示。
- 仅显示存在问题的 Skills 和插件说明；健康清单保留在 `openclaw skills check` 和 `openclaw plugins list` 中。

</details>

<details>
<summary>配置和迁移</summary>

- 旧版值结构的配置规范化。
- 将旧版扁平 `talk.*` 字段中的 Talk 配置迁移至 `talk.provider` + `talk.providers.<provider>`。
- 针对旧版 Chrome 扩展配置和 Chrome MCP 就绪状态的浏览器迁移检查。
- OpenCode 提供商覆盖警告（`models.providers.opencode` / `opencode-zen` / `opencode-go`）。
- 旧版 OpenAI Codex 提供商/配置文件迁移（`openai-codex` → `openai`）以及过时 `models.providers.openai-codex` 的遮蔽警告。
- OpenAI Codex OAuth 配置文件的 OAuth TLS 前置条件检查。
- 当 `plugins.allow` 具有限制性，但工具策略仍请求通配符或插件自有工具时，发出插件/工具允许列表警告。
- 旧版磁盘状态迁移（会话/Agent 目录/WhatsApp 身份验证）。
- 旧版插件清单契约键迁移（`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders` → `contracts`）。
- 旧版定时任务存储迁移（`jobId`、`schedule.cron`、顶层投递/负载字段、负载 `provider`、`notify: true` webhook 回退任务）。
- 在 `agents.defaults`、`agents.entries.*` 和 `models.providers.*`（包括各模型条目）中修复 Codex CLI 运行时固定版本（`agentRuntime.id: "codex-cli"` → `"codex"`）。
- 启用插件时清理过时的插件配置；当 `plugins.enabled=false` 时，过时的插件引用将作为非活动的容纳配置予以保留。

</details>

<details>
<summary>状态和完整性</summary>

- 检查会话锁文件并清理过时锁。
- 修复受影响的 2026.4.24 构建所创建的重复提示词重写分支会话记录。
- 检测卡死的主会话和子智能体重启恢复墓碑。Doctor 会报告被阻塞的会话，并且仅修复与现有墓碑冲突的过时中止标志；不会重新启用自动恢复。
- 状态完整性和权限检查（会话、会话记录、状态目录）。
- 在本地运行时检查配置文件权限（chmod 600）。
- 模型身份验证健康状况：检查 OAuth 过期情况，可刷新即将过期的令牌，并报告身份验证配置文件的冷却/禁用状态。

</details>

<details>
<summary>Gateway 网关、服务和监督器</summary>

- 启用沙箱隔离时修复沙箱镜像。
- 旧版服务迁移和额外 Gateway 网关检测。
- Matrix 渠道旧版状态迁移（在 `--fix` / `--repair` 模式下）。
- Gateway 网关运行时检查（服务已安装但未运行；缓存的 launchd 标签）。
- 渠道状态警告（通过正在运行的 Gateway 网关探测）。
- 渠道特定的权限检查位于 `openclaw channels capabilities` 下；例如，使用 `openclaw channels capabilities --channel discord --target channel:<channel-id>` 审计 Discord 语音频道权限。
- 当本地 TUI 客户端仍在运行时，检查 Gateway 网关事件循环健康状况下降所导致的 WhatsApp 响应问题；`--fix` 仅停止已验证的本地 TUI 客户端。
- 修复主模型、回退模型、图像/视频生成模型、Heartbeat/子智能体/压缩覆盖、Hooks、渠道模型覆盖和会话路由固定项中的旧版 `openai-codex/*` 模型引用；`--fix` 会将其重写为 `openai/*`，将 `openai-codex:*` 身份验证配置文件/顺序迁移至 `openai:*`，移除过时的会话/整个 Agent 运行时固定项，并由修复后的有效路由决定是否与 Codex 兼容。
- 监督器配置审计（launchd/systemd/schtasks），并提供可选修复。
- 清理由 Gateway 网关服务在安装或更新期间从 shell 捕获的嵌入式代理环境 `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` 值。
- Gateway 网关运行时检查（不受支持的旧版 Bun 服务、版本管理器路径）。
- Gateway 网关端口冲突诊断（默认 `18789`）。

</details>

<details>
<summary>身份验证、安全和配对</summary>

- 开放私信策略的安全警告。
- 本地令牌模式的 Gateway 网关身份验证检查（当不存在令牌来源时提供令牌生成功能；不会覆盖令牌 SecretRef 配置）。
- 设备配对问题检测（待处理的首次配对请求、待处理的角色/权限范围升级、过时的本地设备令牌缓存偏移，以及已配对记录的身份验证偏移）。

</details>

<details>
<summary>工作区和 shell</summary>

- Linux 上的 systemd linger 检查。
- 工作区引导文件大小检查（上下文文件截断/接近上限警告）。
- 默认智能体的 Skills 就绪状态检查；报告缺少二进制文件、环境、配置或操作系统要求的已允许 Skills，且 `--fix` 可在 `skills.entries` 中禁用不可用的 Skills。
- shell 补全状态检查及自动安装/升级。
- 记忆搜索嵌入提供商就绪状态检查（本地模型、远程 API key 或 QMD 二进制文件）。
- 源代码安装检查（pnpm 工作区不匹配、缺少 UI 资源、缺少 tsx 二进制文件）。
- 写入更新后的配置 + 向导元数据。

</details>

## Dreams UI 回填和重置

  Control UI 的 Dreams 场景包含用于 grounded dreaming 工作流的 **Backfill**、**Reset** 和 **Clear Grounded** 操作。这些操作使用 Gateway 网关 Doctor 风格的 RPC 方法，但**不**属于 `openclaw doctor` CLI 修复/迁移。

  | 操作           | 功能                                                                                                                                                              |
  | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | Backfill       | 扫描活动工作区中的历史 `memory/YYYY-MM-DD.md` 文件，运行 grounded REM 日记流程，并将可逆的回填条目写入 `DREAMS.md`。 |
  | Reset          | 仅从 `DREAMS.md` 中移除已标记的回填日记条目。                                                                                                              |
  | Clear Grounded | 仅移除历史重放中尚未积累实时召回或每日支持的暂存 grounded-only 短期条目。                                                                                           |

  这些操作均不会编辑 `MEMORY.md`、运行完整的 Doctor 迁移，也不会自行将 grounded 候选项暂存到实时短期晋升存储中。要将 grounded 历史重放送入常规深度晋升通道，请改用以下 CLI 流程：

  ```bash
  openclaw memory rem-backfill --path ./memory --stage-short-term
  ```

  该命令会将 grounded 持久候选项暂存到短期 dreaming 存储中，同时 `DREAMS.md` 仍作为审查界面。

  ## 详细行为和设计理由

<details>
<summary>0. 可选更新（git 安装）</summary>

如果这是 git 检出，并且 Doctor 正以交互方式运行，它会在运行 Doctor 前提示更新（fetch/rebase/build）。

</details>

<details>
<summary>1. 配置规范化</summary>

Doctor 会将旧版值结构规范化为当前 schema。当前 Talk 语音配置为 `talk.provider` + `talk.providers.<provider>`，实时语音配置位于 `talk.realtime.*` 下。Doctor 会将旧的 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / `talk.apiKey` 结构重写到提供商映射中，并将旧版顶层实时选择器（`talk.mode`、`talk.transport`、`talk.brain`、`talk.model`、`talk.voice`）重写到 `talk.realtime` 中。

当 `plugins.allow` 非空且工具策略使用通配符或插件自有工具条目时，Doctor 也会发出警告。`tools.allow: ["*"]` 仅匹配实际加载的插件所提供的工具；它不会绕过排他性插件允许列表。

</details>

<details>
<summary>2. 旧版配置键迁移</summary>

当配置包含具有有效迁移路径的弃用键时，其他命令会拒绝运行，并要求你运行 `openclaw doctor`。Doctor 会说明发现了哪些旧版键、显示已应用的迁移，并使用更新后的 schema 重写 `~/.openclaw/openclaw.json`。Gateway 网关启动时会拒绝旧版配置格式，并要求你运行 `openclaw doctor --fix`；启动过程中不会重写 `openclaw.json`。定时任务存储迁移也由 `openclaw doctor --fix` 处理。

<div class="callout callout-note">

Doctor 仅在某个键停用后的大约两个月内提供自动迁移。更早的旧版键（例如最初的
`routing.queue`、`routing.bindings`、`routing.agents`/`defaultAgentId`、
`routing.transcribeAudio`、顶层 `agent.*`，或多智能体配置结构出现之前的顶层 `identity`）
已不再具有迁移路径；使用这些键的配置现在会验证失败，而不会被重写。请根据当前配置参考手动修复
这些键，之后 Doctor 才能继续运行。

</div>

有效迁移：

| 旧键                                                                                    | 当前键                                                                 |
| ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| `routing.allowFrom`                                                                              | `channels.whatsapp.allowFrom`                                                |
| `routing.groupChat.requireMention`                                                               | `channels.whatsapp/telegram/imessage.groups."*".requireMention`             |
| `routing.groupChat.historyLimit`                                                                 | `messages.groupChat.historyLimit`                                            |
| `routing.groupChat.mentionPatterns`                                                              | `messages.groupChat.mentionPatterns`                                         |
| `channels.telegram.requireMention`                                                               | `channels.telegram.groups."*".requireMention`                               |
| `channels.webchat`、`gateway.webchat`                                                            | 已移除（WebChat 已停用）                                                 |
| `channels.feishu.accounts.<accountId>.botName`                                                   | `channels.feishu.accounts.<accountId>.name`                                 |
| `session.threadBindings.ttlHours`、`channels.<id>.threadBindings.ttlHours`（以及各账户对应项）      | `...threadBindings.idleHours`                                               |
| 旧版 `talk.voiceId`/`talk.voiceAliases`/`talk.modelId`/`talk.outputFormat`/`talk.apiKey`        | `talk.provider` + `talk.providers.<provider>`                               |
| 旧版顶层实时 Talk 选择器（`talk.mode`/`talk.transport`/`talk.brain`/`talk.model`/`talk.voice`） | `talk.realtime`                                                              |
| `messages.tts`                                                                                  | 顶层 `tts`                                                              |
| `messages.tts.<provider>`（`openai`/`elevenlabs`/`microsoft`/`edge`）                             | `tts.providers.<provider>`                                                   |
| `messages.tts.provider: "edge"` / `messages.tts.providers.edge`                                  | `tts.provider: "microsoft"` / `tts.providers.microsoft`                    |
| `tools.exec.security` + `tools.exec.ask`                                                         | `tools.exec.mode`                                                            |
| `session.idleMinutes`                                                                            | `session.reset.idleMinutes`                                                  |
| 带有显式渠道块的 `messages.responsePrefix`                                           | 复制到已配置渠道/账户的 `responsePrefix`；为隐式/自定义渠道保留全局回退 |
| `web.enabled`                                                                                    | `channels.whatsapp.enabled`                                                  |
| `meta.lastTouchedAt`、钩子安装、定时任务存储、内置设备发现、全局 TTS 偏好设置路径            | 共享 SQLite 状态                                                       |
| TTS 说话人字段 `voice`/`voiceName`/`voiceId`                                                 | `speakerVoice`/`speakerVoiceId`                                              |
| `channels.<id>.tts.<provider>` / `channels.<id>.accounts.<accountId>.tts.<provider>`（除 Discord 外的所有渠道）                                          | `...tts.providers.<provider>`                                                |
| `channels.<id>.voice.tts.<provider>` / `channels.<id>.accounts.<accountId>.voice.tts.<provider>`（所有渠道，包括 Discord）                          | `...voice.tts.providers.<provider>`                                          |
| `plugins.entries.voice-call.config.tts.<provider>`（`openai`/`elevenlabs`/`microsoft`/`edge`）     | `plugins.entries.voice-call.config.tts.providers.<provider>`                |
| `plugins.entries.voice-call.config.tts.provider: "edge"` / `...tts.providers.edge`                | `provider: "microsoft"` / `...tts.providers.microsoft`                      |
| `plugins.entries.voice-call.config.provider: "log"`                                              | `"mock"`                                                                      |
| `plugins.entries.voice-call.config.twilio.from`                                                  | `plugins.entries.voice-call.config.fromNumber`                              |
| `plugins.entries.voice-call.config.streaming.sttProvider`                                        | `plugins.entries.voice-call.config.streaming.provider`                      |
| `plugins.entries.voice-call.config.streaming.openaiApiKey`/`sttModel`/`silenceDurationMs`/`vadThreshold` | `plugins.entries.voice-call.config.streaming.providers.openai.*`             |
| `models.providers.*.api: "openai"`                                                               | `"openai-completions"`（Gateway 网关启动时也会跳过 `api` 为未来/未知枚举值的提供商，而不是以拒绝方式失败） |
| `browser.ssrfPolicy.allowPrivateNetwork`                                                         | `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`                          |
| `browser.profiles.*.driver: "extension"`                                                         | `"existing-session"`                                                          |
| `browser.relayBindHost`                                                                          | 已移除（旧版 Chrome 扩展中继设置）                             |
| `mcp.servers.*.type`（CLI 原生别名）                                                        | `mcp.servers.*.transport`                                                    |
| `mcp.servers.*.disabled`                                                                         | 反向的 `mcp.servers.*.enabled`                                              |
| MCP 超时别名 `connectTimeout`/`connect_timeout`/`timeout`                                 | `connectionTimeoutMs`/`requestTimeoutMs`                                    |
| MCP 蛇形命名服务器字段                                                                     | 驼峰命名 MCP 服务器字段                                                   |
| `tools.media.image/audio/video.models`                                                           | 带能力标签的 `tools.media.models`                                        |
| `tools.media.asyncCompletion`                                                                    | 已移除                                                                       |
| `tools.message.allowCrossContextSend`                                                            | `tools.message.crossContext`                                                  |
| 媒体模型 `deepgram` 选项                                                                   | `providerOptions.deepgram`                                                    |
| `talk.realtime.voice`、Discord 实时 `voice`                                                 | `speakerVoice`                                                                |
| `agents.defaults.pdfMaxBytesMb`                                                                  | `agents.defaults.pdfMaxMb`                                                    |
| `tools.exec.timeoutSec`                                                                          | `tools.exec.timeoutSeconds`                                                   |
| `browser.ssrfPolicy.hostnameAllowlist`                                                           | 支持通配符的 `browser.ssrfPolicy.allowedHostnames`                          |
| 沙箱浏览器 `enableNoVnc`                                                                    | `noVncEnabled`                                                                |
| 根级 `media`                                                                                     | `attachments`                                                                |
| 渠道/账户 `heartbeat` 可见性块                                                   | `heartbeatVisibility`                                                         |
| `channels.slack.identity`                                                                        | `channels.slack.postAs`                                                       |
| 根级 `audit`                                                                                     | `logging.audit`                                                               |
| `gateway.nodes.skills.enabled`                                                                   | `gateway.nodes.allowSkills`                                                   |
| `gateway.nodes.allowCommands`/`denyCommands`                                                    | `gateway.nodes.commands.allow`/`deny`                                         |
| 生成模型默认值                                                                       | `agents.defaults.mediaModels.{image,video,music}`                              |
| 已停用的最终布局调节选项                                                               | 内置默认行为                                                     |
| `channels.whatsapp.messagePrefix` 和旧版 `messages.messagePrefix`                            | `channels.whatsapp.responsePrefix`                                            |
| `channels.whatsapp.ackReaction`                                                                  | 全局 `messages.ackReaction`，以及可翻译位置中的 `ackReactionScope`        |
| `cron.failureDestination`                                                                        | `cron.failureAlert` 上的目标字段                                     |
| `gateway.controlUi.chatMessageMaxWidth`、仅用于呈现的 `ui.prefs` 键                       | 已移除（文本缩放、聊天宽度和实时侧边栏活动均由浏览器在本地管理） |
| `agents.list`                                                                                    | 以键区分的 `agents.entries`                                                        |
| 顶层 `defaultModel`                                                                         | `agents.defaults.model`                                                      |
| `messages.messagePrefix`                                                                         | `channels.whatsapp.responsePrefix`                                            |
| `session.maintenance.pruneDays`、`session.resetByType.dm`                                        | `session.maintenance.pruneAfter`、`session.resetByType.direct`               |
| 顶层 `tui`                                                                                  | 已移除（TUI 页脚使用紧凑默认样式）                            |
| `plugins.entries.codex.config.codexDynamicToolsProfile`                                          | 已移除（Codex app-server 始终让 Codex 原生工作区工具保持原生） |
| `commands.modelsWrite`                                                                           | 已移除（`/models add` 已弃用）                                       |
| `agents.defaults/list[].silentReplyRewrite`、`surfaces.*.silentReplyRewrite`                     | 已移除（不再将完全匹配的 `NO_REPLY` 重写为可见的回退文本）  |
| `agents.defaults/list[].systemPromptOverride`                                                    | 已移除（OpenClaw 负责生成系统提示词）                        |
| `agents.defaults/list[].embeddedPi`                                                              | `embeddedAgent`                                                              |
| `agents.defaults/list[].sandbox.perSession`                                                      | `sandbox.scope`                                                              |
| `agents.defaults.llm`                                                                             | 已移除（对于缓慢的模型/提供商超时，请使用 `models.providers.<id>.timeoutSeconds`，其值应保持低于智能体/运行超时上限） |
| 顶层 `memorySearch`、`agents.defaults.memorySearch`                                         | `memory.search`                                                             |
| `agents.entries.*.memorySearch`                                                                     | `agents.entries.*.memory.search`                                               |
| `memorySearch.provider: "auto"`                                                                  | `"openai"`                                                                    |
| `memorySearch.store.path`（任意层级）                                                            | 已移除（记忆索引存储在各 Agent 数据库中）                       |
| 顶层 `heartbeat`                                                                            | `agents.defaults.heartbeat` / `channels.defaults.heartbeat`                 |
| `plugins.openai-codex` 策略 ID                                                                | `plugins.openai`                                                             |
| `tools.web.x_search.apiKey`                                                                      | `plugins.entries.xai.config.webSearch.apiKey`                               |
| `session.maintenance.rotateBytes`、`session.parentForkMaxTokens`                                 | 已移除（已弃用）                                                        |
| 2026.7 中停用的运行时和渠道调优选项                                               | 已移除（应用内置生产环境默认值）                               |

<div class="callout callout-note">

上述 `plugins.entries.voice-call.config.*` 行会在每次加载配置时由
语音通话插件自身进行规范化，而不是由 `openclaw
doctor` 处理。该插件还会记录一条指向 `openclaw
doctor --fix` 的启动警告，但 Doctor 目前不会针对这些键重写
`openclaw.json`；运行时应用此更改的是插件自身的规范化逻辑。

</div>

多账户渠道的账户默认值指南：

- 如果配置了两个或更多 `channels.<channel>.accounts` 条目，但未配置 `channels.<channel>.defaultAccount` 或 `accounts.default`，Doctor 会警告后备路由可能会选择非预期账户。
- 如果将 `channels.<channel>.defaultAccount` 设置为未知账户 ID，Doctor 会发出警告并列出已配置的账户 ID。

</details>

<details>
<summary>2b. OpenCode 提供商覆盖</summary>

如果你手动添加了 `models.providers.opencode`、`opencode-zen` 或 `opencode-go`，它会覆盖来自 `openclaw/plugin-sdk/llm` 的内置 OpenCode 目录。这可能会迫使模型使用错误的 API，或将费用归零。Doctor 会发出警告，以便你移除该覆盖并恢复按模型设置的 API 路由和费用。

</details>

<details>
<summary>2c. 浏览器迁移和 Chrome MCP 就绪状态</summary>

如果你的浏览器配置仍指向已移除的 Chrome 扩展路径，Doctor 会将其规范化为当前的主机本地 Chrome MCP 附加模型（`browser.profiles.*.driver: "extension"` → `"existing-session"`；移除 `browser.relayBindHost`）。

当你使用 `defaultProfile: "user"` 或已配置的 `existing-session` 配置文件时，Doctor 还会检查主机本地 Chrome MCP 路径：

- 对于默认自动连接配置文件，检查同一主机上是否安装了 Google Chrome
- 检查检测到的 Chrome 版本，并在低于 Chrome 144 时发出警告
- 提醒你在浏览器检查页面中启用远程调试（例如 `chrome://inspect/#remote-debugging`、`brave://inspect/#remote-debugging` 或 `edge://inspect/#remote-debugging`）

Doctor 无法替你启用 Chrome 端的设置。主机本地 Chrome MCP 仍要求 Gateway 网关/节点主机上本地运行基于 Chromium 的 144+ 浏览器、启用远程调试，并在浏览器中批准首次附加同意提示。

此处的就绪状态仅涵盖本地附加的先决条件。现有会话会保留当前的 Chrome MCP 路由限制；`responsebody`、PDF 导出、下载拦截和批量操作等高级路由仍需要托管浏览器或原始 CDP 配置文件。此检查不适用于 Docker、沙箱、远程浏览器或其他无头流程，这些流程会继续使用原始 CDP。

</details>

<details>
<summary>2d. OAuth TLS 先决条件</summary>

配置 OpenAI Codex OAuth 配置文件后，Doctor 会探测 OpenAI 授权端点，以验证本地 Node/OpenSSL TLS 栈能否验证证书链。如果探测因证书错误而失败（例如 `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、证书过期或自签名证书），Doctor 会输出特定于平台的修复指南。在 macOS 上使用 Homebrew Node 时，修复方法通常是 `brew postinstall ca-certificates`。使用 `--deep` 时，即使 Gateway 网关运行正常，也会执行该探测。

</details>

<details>
<summary>2e. Codex OAuth 提供商覆盖</summary>

如果你之前在 `models.providers.openai-codex` 下添加了旧版 OpenAI 传输设置，它们可能会遮蔽内置的 Codex OAuth 提供商路径。当 Doctor 发现这些旧传输设置与 Codex OAuth 并存时，会发出警告，以便你移除或重写过时的传输覆盖并恢复当前的路由行为。自定义代理和仅标头覆盖仍受支持，不会触发此警告，但这些手动定义的请求路由不符合隐式选择 Codex 的条件。

</details>

<details>
<summary>2f. Codex 路由修复</summary>

Doctor 会检查旧版 `openai-codex/*` 模型引用。原生 Codex harness 路由使用规范的 `openai/*` 模型引用，但仅凭前缀永远不会选择 Codex。当运行时策略未设置或为 `auto` 时，只有没有手动定义请求覆盖、且与官方 HTTPS Platform Responses 或 ChatGPT Responses 完全匹配的路由才符合条件。请参阅 [OpenAI 隐式 Agent runtime](https://funcoding.ai/agents/openclaw/providers/openai/#implicit-agent-runtime)。

在 `--fix` / `--repair` 模式下，Doctor 会重写受影响的默认 Agent 和按 Agent 配置的引用，包括主模型、后备模型、图像/视频生成模型、Heartbeat/子智能体/压缩覆盖、Hooks、渠道模型覆盖以及过时的持久化会话路由状态：

- `openai-codex/gpt-*` 变为 `openai/gpt-*`。
- 对于已修复的 Agent 模型引用，Codex 意图会移至提供商/模型范围的 `agentRuntime.id: "codex"` 条目。
- 会移除过时的整个 Agent 运行时配置和持久化会话运行时固定值，因为运行时选择以提供商/模型为范围。
- 除非修复后的旧版模型引用需要 Codex 路由来保留旧身份验证路径，否则会保留现有的提供商/模型运行时策略。
- 会保留现有模型后备列表并重写其中的旧版条目；复制的按模型设置会从旧版键移至规范的 `openai/*` 键。
- 会在所有已发现的 Agent 会话存储中修复持久化会话的 `modelProvider`/`providerOverride`、`model`/`modelOverride`、后备通知和身份验证配置文件固定值。
- Doctor 还会单独修复过时的 `agentRuntime.id: "codex-cli"` 固定值（一个不同的旧版运行时 ID），将 `agents.defaults`、`agents.entries.*` 和 `models.providers.*` 模型条目中的这些值改为 `"codex"`。
- `/codex ...` 表示“从聊天中控制原生 Codex 对话或与其绑定”。
- `/acp ...` 或 `runtime: "acp"` 表示“使用外部 ACP/acpx 适配器”。

</details>

<details>
<summary>2g. 会话路由清理</summary>

将已配置的模型或运行时从 Codex 等插件自有路由移走后，Doctor 还会扫描已发现的 Agent 会话存储，查找过时的自动创建路由状态。

当路由所有者不再配置时，`openclaw doctor --fix` 可以清除自动创建的过时状态，例如 `modelOverrideSource: "auto"` 模型固定值、运行时模型元数据、已固定的 harness ID、CLI 会话绑定以及自动身份验证配置文件覆盖。显式的用户或旧版会话模型选择会报告出来供手动检查，并保持不变；当不再需要该路由时，请使用 `/model ...`、`/new` 切换它们，或重置会话。

</details>

<details>
<summary>3. 旧版状态迁移（磁盘布局）</summary>

Doctor 可以将旧版磁盘布局迁移到当前结构：

- 会话存储和记录：从 `~/.openclaw/sessions/` 迁移到 `~/.openclaw/agents/<agentId>/sessions/`
- Agent 目录：从 `~/.openclaw/agent/` 迁移到 `~/.openclaw/agents/<agentId>/agent/`
- WhatsApp 身份验证状态（Baileys）：从旧版 `~/.openclaw/credentials/*.json`（`oauth.json` 除外）迁移到 `~/.openclaw/credentials/whatsapp/<accountId>/...`（默认账户 ID：`default`）
- 签名设备身份：从 `~/.openclaw/identity/device.json` 迁移到 `state/openclaw.sqlite` 中 `primary` 的 `device_identities` 行；单独的设备身份验证文件保持不变

这些迁移会尽力执行且具有幂等性；当 Doctor 将任何旧版文件夹留作备份时，会发出警告。Gateway 网关/CLI 也会在启动时自动迁移旧版会话和 Agent 目录，因此无需手动运行 Doctor，历史记录/身份验证/模型即可迁移到按 Agent 配置的路径。WhatsApp 身份验证特意仅通过 `openclaw doctor` 迁移。Talk 提供商/提供商映射规范化使用结构相等性进行比较，因此仅键顺序不同的差异不再重复触发无实际变更的 `doctor --fix` 修改。

</details>

<details>
<summary>3a. 旧版插件清单迁移</summary>

Doctor 会扫描所有已安装的插件清单，查找已弃用的顶层能力键（`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders`）。发现后，它会提议将这些键移入 `contracts` 对象，并原地重写清单文件。此迁移具有幂等性；如果 `contracts` 中已存在相同值，则会移除旧版键而不重复数据。

</details>

<details>
<summary>3b. 旧版定时任务存储迁移</summary>

在将规范行导入 SQLite 之前，Doctor 还会检查旧版定时任务存储（`~/.openclaw/cron/jobs.json`）中的旧任务结构。

当前的定时任务清理包括：

- `jobId` → `id`
- `schedule.cron` → `schedule.expr`
- 顶层载荷字段（`message`、`model`、`thinking`，……）→ `payload`
- 顶层投递字段（`deliver`、`channel`、`to`、`provider`，……）→ `delivery`
- 载荷 `provider` 投递别名 → 显式 `delivery.channel`
- 旧版 `notify: true` webhook 后备任务 → 如果已停用的原始 `cron.webhook` 值有效，则转换为显式 webhook 投递；公告任务保留其聊天投递并获得 `delivery.completionDestination`。然后 Doctor 会移除旧配置键。如果没有可用的旧版 webhook，则会移除无目标任务中不起作用的顶层 `notify` 标记（保留现有投递，包括公告），因为运行时投递永远不会读取它。

Gateway 网关还会在加载时清理格式错误的定时任务行，使有效任务能够继续运行。从 `jobs.json` 中移除格式错误的原始行之前，会将其复制到活动存储旁的 `jobs-quarantine.json`；Doctor 会报告已隔离的行，以便你手动检查或修复。

Gateway 网关启动时会规范化运行时投影并忽略顶层 `notify` 标记，但会保留持久化的定时任务状态供 Doctor 修复。Doctor 会移除没有迁移目标的任务中不起作用的标记（`delivery.mode` 为 none/不存在、旧版 webhook 目标不可用或已有公告/聊天投递），同时保持现有投递不变，因此重复运行 `doctor --fix` 时不再针对同一任务重复发出警告。

在 Linux 上，如果用户的 crontab 仍调用旧版 `~/.openclaw/bin/ensure-whatsapp.sh`，Doctor 也会发出警告。当前的 OpenClaw 不维护该主机本地脚本；当 cron 无法访问 systemd 用户总线时，该脚本可能会向 `~/.openclaw/logs/whatsapp-health.log` 写入错误的 `Gateway inactive` 消息。使用 `crontab -e` 移除过时的 crontab 条目；使用 `openclaw channels status --probe`、`openclaw doctor` 和 `openclaw gateway status` 执行当前的健康检查。

</details>

<details>
<summary>3c. 会话锁清理</summary>

Doctor 会扫描每个智能体会话目录，查找会话异常退出后遗留的过期写入锁文件。对于找到的每个锁文件，它都会报告：路径、PID、该 PID 是否仍在运行、锁存在时长，以及是否被视为过期（PID 已终止、所有者元数据格式错误、超过 30 分钟，或已确认仍在运行的 PID 属于非 OpenClaw 进程）。在 `--fix` / `--repair` 模式下，它会自动移除所有者已终止、已成为孤儿、已被回收、格式错误且陈旧或非 OpenClaw 的锁。对于仍由正在运行的 OpenClaw 进程持有的旧锁，Doctor 会报告但保留它们，以免中断正在写入转录记录的进程。

</details>

<details>
<summary>3d. 会话转录记录分支修复</summary>

Doctor 会扫描智能体会话 JSONL 文件，查找由 2026.4.24 提示词转录记录重写错误所产生的重复分支结构：一个已放弃的用户轮次包含 OpenClaw 内部运行时上下文，同时有一个活跃的同级分支包含相同的可见用户提示词。在 `--fix` / `--repair` 模式下，Doctor 会在每个受影响文件的原文件旁创建备份，然后将转录记录重写为活跃分支，使 Gateway 网关历史记录和记忆读取器不再看到重复轮次。

</details>

<details>
<summary>4. 状态完整性检查（会话持久化、路由和安全）</summary>

状态目录是系统运行的脑干。如果它消失，除非你在其他位置有备份，否则会丢失会话、凭据、日志和配置。

Doctor 会检查：

- **状态目录缺失**：警告状态已发生灾难性丢失，提示重新创建目录，并提醒你它无法恢复缺失的数据。
- **状态目录权限**：验证是否可写；提供修复权限的选项（检测到所有者/组不匹配时还会显示 `chown` 提示）。
- **macOS 云同步状态目录**：当状态目录解析到 iCloud Drive（`~/Library/Mobile Documents/com~apple~CloudDocs/...`）或 `~/Library/CloudStorage/...` 下时发出警告，因为同步支持的路径可能导致 I/O 变慢以及锁定/同步竞态。
- **Linux SD 或 eMMC 状态目录**：当状态目录解析到 `mmcblk*` 挂载源时发出警告，因为在写入会话和凭据时，基于 SD/eMMC 的随机 I/O 可能更慢且磨损更快。
- **Linux 易失性状态目录**：当状态目录解析到 `tmpfs` 或 `ramfs` 时发出警告，因为会话、凭据、配置和 SQLite 状态（包括 WAL/日志边车文件）会在重启时消失。Docker `overlay` 挂载有意不会被标记，因为只要容器仍然存在，其可写层就能在主机重启后继续保留。
- **会话目录缺失**：必须存在 `sessions/` 和会话存储目录，才能持久保存历史记录并避免 `ENOENT` 崩溃。
- **转录记录不匹配**：当近期会话条目缺少转录记录文件时发出警告。
- **主会话“单行 JSONL”**：当主转录记录只有一行时进行标记（历史记录未持续累积）。
- **多个状态目录**：当不同主目录中存在多个 `~/.openclaw` 文件夹，或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告（历史记录可能分散在不同安装中）。
- **远程模式提醒**：如果 `gateway.mode=remote`，Doctor 会提醒你在远程主机上运行它（状态存储在那里）。
- **配置文件权限**：如果 `~/.openclaw/openclaw.json` 对组/所有用户可读，则发出警告并提供将权限收紧为 `600` 的选项。

</details>

<details>
<summary>5. 模型身份验证健康状态（OAuth 到期）</summary>

Doctor 会检查身份验证存储中的 OAuth 配置文件，在令牌即将到期或已经到期时发出警告，并可在安全的情况下刷新令牌。如果 Anthropic OAuth/令牌配置文件已过期，它会建议使用 Anthropic API 密钥或 Anthropic 设置令牌路径。仅在交互式运行（TTY）时才会显示刷新提示；`--non-interactive` 会跳过刷新尝试。

当 OAuth 刷新永久失败时（例如 `refresh_token_reused`、`invalid_grant`，或提供商要求你重新登录），Doctor 会报告需要重新进行身份验证，并输出要运行的确切 `openclaw models auth login --provider ...` 命令。

Doctor 还会报告因短期冷却（速率限制/超时/身份验证失败）或较长时间禁用（账单/额度失败）而暂时无法使用的身份验证配置文件。

对于令牌存储在 macOS 钥匙串中的旧版 Codex OAuth 配置文件（采用基于文件的边车布局之前的旧版新手引导），只能由 Doctor 进行修复。在交互式终端中运行一次 `openclaw doctor --fix`，将由钥匙串支持的旧版令牌就地迁移到 `auth-profiles.json`；之后，嵌入式轮次（Telegram、定时任务、子智能体调度）会将它们解析为规范的 OpenAI OAuth 配置文件。

</details>

<details>
<summary>6. Hooks 模型验证</summary>

如果设置了 `hooks.gmail.model`，Doctor 会根据目录和允许列表验证模型引用，并在该引用无法解析或不被允许时发出警告。

</details>

<details>
<summary>7. 沙箱镜像修复</summary>

启用沙箱隔离后，Doctor 会检查 Docker 镜像；如果当前镜像缺失，它会提供构建镜像或切换到旧版名称的选项。

</details>

<details>
<summary>7b. 插件安装清理</summary>

在 `openclaw doctor --fix` / `openclaw doctor --repair` 模式下，Doctor 会移除由 OpenClaw 生成的旧版插件依赖暂存状态：过期的已生成依赖根目录、旧安装暂存目录、早期内置插件依赖修复代码留下的包内杂项，以及内置 `@openclaw/*` 插件的孤立或已恢复托管 npm 副本，这些副本可能遮蔽当前内置清单。Doctor 还会将主机的 `openclaw` 包重新链接到声明了 `peerDependencies.openclaw` 的托管 npm 插件中，使 `openclaw/plugin-sdk/*` 等包内运行时导入在更新或 npm 修复后仍可正常解析。

当配置引用了缺失的可下载插件，但本地插件注册表找不到它们时，Doctor 还可以重新安装这些插件（重要的 `plugins.entries`、已配置的渠道/提供商/搜索设置、已配置的 Agent Runtimes）。在包更新期间，核心包正被替换时，Doctor 会避免重新安装插件包；如果更新后已配置的插件仍需恢复，请再次运行 `openclaw doctor --fix`。除下述容器镜像启动例外情况外，Gateway 网关启动和配置重新加载不会执行包修复；插件安装仍需通过显式的 Doctor/安装/更新操作完成。

容器化 Gateway 网关启动存在一项范围严格的升级例外：当 `openclaw gateway run` 在新版 OpenClaw 上启动时，它会在就绪前运行安全状态迁移和现有的核心更新后插件收敛流程，然后记录每个版本的检查点。此启动流程可以清理过期的内置插件记录、修复本地插件链接、在收敛路径需要时重新安装已配置的插件包，并检查活跃插件载荷。如果启动过程无法安全修复，请针对同一挂载状态/配置，使用 `openclaw doctor --fix` 运行同一镜像一次，然后再正常重启容器。

</details>

<details>
<summary>8. Gateway 网关服务迁移和清理提示</summary>

Doctor 会检测旧版 Gateway 网关服务（launchd/systemd/schtasks），提供移除这些服务并使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。它还可以扫描其他类似 Gateway 网关的服务并输出清理提示。按配置文件命名的 OpenClaw Gateway 网关服务被视为一等服务，不会被标记为“额外”服务。

在 Linux 上，如果缺少用户级 Gateway 网关服务，但存在系统级 OpenClaw Gateway 网关服务，Doctor 不会自动安装第二个用户级服务。使用 `openclaw gateway status --deep` 或 `openclaw doctor --deep` 检查，然后移除重复服务；如果 Gateway 网关生命周期由系统监督程序管理，则设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。

</details>

<details>
<summary>8b. 启动时 Matrix 迁移</summary>

当 Matrix 渠道账号存在待处理或可执行的旧版状态迁移时，Doctor（在 `--fix` / `--repair` 模式下）会创建迁移前快照，然后运行尽力而为的迁移步骤：旧版 Matrix 状态迁移和旧版加密状态准备。这两个步骤均为非致命步骤；错误会被记录，启动过程会继续。在只读模式（`openclaw doctor` 且不含 `--fix`）下，会完全跳过此检查。

</details>

<details>
<summary>8c. 设备配对和身份验证漂移</summary>

Doctor 会在常规健康检查过程中检查设备配对状态，并报告：

- 待处理的首次配对请求
- 已配对设备待处理的角色或权限范围升级
- 设备 ID 仍匹配，但设备身份不再与已批准记录匹配时的公钥不匹配修复
- 已配对记录缺少已批准角色的有效令牌
- 权限范围偏离已批准配对基线的已配对令牌
- 当前计算机上早于 Gateway 网关端令牌轮换或包含过期权限范围元数据的本地缓存设备令牌条目

Doctor 不会自动批准配对请求或自动轮换设备令牌。它会输出确切的后续步骤：

- 使用 `openclaw devices list` 检查待处理请求
- 使用 `openclaw devices approve <requestId>` 批准确切请求
- 使用 `openclaw devices rotate --device <deviceId> --role <role>` 轮换新的令牌
- 使用 `openclaw devices remove <deviceId>` 移除并重新批准过期记录

这可以区分首次配对、待处理的角色/权限范围升级以及过期令牌/设备身份漂移，从而解决常见的“已配对但仍提示需要配对”问题。

</details>

<details>
<summary>9. 安全警告</summary>

Doctor 仅在发现警告时才会显示安全说明，例如提供商允许不在允许列表中的用户发送私信，或策略配置存在危险。使用 `openclaw security audit` 查看完整的安全清单。

</details>

<details>
<summary>10. systemd linger（Linux）</summary>

如果作为 systemd 用户服务运行，Doctor 会确保启用 linger，使 Gateway 网关在退出登录后继续运行。

</details>

<details>
<summary>11. 工作区状态（Skills、插件和 TaskFlows）</summary>

Doctor 会输出默认智能体的问题和操作，而非健康状态清单：

- **Skills**：列出允许但无法使用的技能名称；使用 `openclaw skills check` 查看要求详情和完整计数。
- **插件**：仅报告出错的插件 ID；使用 `openclaw plugins list` 查看已加载、已导入、已禁用以及内置插件清单。
- **插件兼容性警告**：标记与当前运行时存在兼容性问题的插件。
- **插件诊断**：显示插件注册表在加载时发出的所有警告或错误。
- **TaskFlow 恢复**：显示需要手动检查或取消的可疑托管 TaskFlow。
- **Claude CLI**：仅报告二进制文件、身份验证、配置文件、工作区或项目目录问题；省略健康探测详情。

</details>

<details>
<summary>11b. 引导文件大小</summary>

Doctor 会检查工作区引导文件（例如 `AGENTS.md`、`CLAUDE.md` 或其他注入的上下文文件）是否接近或超过配置的字符预算。它会报告每个文件的原始字符数与注入字符数、截断百分比、截断原因（`max/file` 或 `max/total`），以及总注入字符数占总预算的比例。当文件被截断或接近限制时，Doctor 会输出调整 `agents.defaults.bootstrapMaxChars` 和 `agents.defaults.bootstrapTotalMaxChars` 的提示。

</details>

<details>
<summary>11c. Shell 补全</summary>

Doctor 会检查当前 Shell（zsh、bash、fish 或 PowerShell）是否已安装 Tab 补全：

- 如果 shell 配置文件使用缓慢的动态补全模式（`source <(openclaw completion ...)`），Doctor 会将其升级为速度更快的缓存文件变体。
- 如果配置文件中已配置补全，但缓存文件缺失，Doctor 会自动重新生成缓存。
- 如果完全未配置补全，Doctor 会提示安装（仅限交互模式；使用 `--non-interactive` 时跳过）。

运行 `openclaw completion --write-state` 可手动重新生成缓存。

</details>

<details>
<summary>11d. 清理过期的渠道插件</summary>

当 `openclaw doctor --fix` 移除缺失的渠道插件时，还会移除引用该插件的悬空渠道级配置：`channels.<id>` 条目、指定该渠道的 Heartbeat 目标以及 `agents.*.models["<channel>/*"]` 覆盖项。这样可防止渠道运行时已不存在，但配置仍要求 Gateway 网关绑定到该渠道而导致的 Gateway 网关启动循环。

</details>

<details>
<summary>12. Gateway 网关身份验证检查（本地令牌）</summary>

Doctor 会检查本地 Gateway 网关令牌身份验证是否就绪。

- 如果令牌模式需要令牌，但不存在令牌来源，Doctor 会提议生成一个令牌。
- 如果 `gateway.auth.token` 由 SecretRef 管理但不可用，Doctor 会发出警告，且不会用明文覆盖它。
- `openclaw doctor --generate-gateway-token` 仅在未配置令牌 SecretRef 时强制生成令牌。

</details>

<details>
<summary>12b. 感知 SecretRef 的只读修复</summary>

某些修复流程需要检查已配置的凭据，同时不削弱运行时的快速失败行为。

- `openclaw doctor --fix` 使用与状态类命令相同的只读 SecretRef 摘要模型来执行针对性的配置修复。
- 示例：Telegram `allowFrom` / `groupAllowFrom` `@username` 修复会在已配置 Bot 凭据可用时尝试使用这些凭据。
- 如果 Telegram Bot 令牌通过 SecretRef 配置，但在当前命令路径中不可用，Doctor 会报告该凭据“已配置但不可用”并跳过自动解析，而不是崩溃或错误地报告令牌缺失。

</details>

<details>
<summary>13. Gateway 健康检查与重启</summary>

Doctor 会运行健康检查，并在 Gateway 网关看起来不健康时提议重启。

</details>

<details>
<summary>13b. 记忆搜索就绪状态</summary>

Doctor 会检查为默认智能体配置的记忆搜索嵌入提供商是否就绪。具体行为取决于已配置的后端和提供商：

- **QMD 后端**：探测 `qmd` 二进制文件是否可用且能够启动。如果不可用，则输出修复指导，包括 `npm install -g @tobilu/qmd`（或对应的 Bun 命令）以及手动指定二进制文件路径的选项。
- **显式本地提供商**：检查本地模型文件或已识别的远程/可下载模型 URL。如果缺失，则建议切换到远程提供商。
- **显式远程提供商**（`openai`、`voyage` 等）：验证环境或身份验证存储中是否存在 API 密钥。如果缺失，则输出可直接执行的修复提示。
- **旧版自动提供商**：将 `memorySearch.provider: "auto"` 视为 OpenAI，检查 OpenAI 就绪状态，并由 `doctor --fix` 将其重写为 `provider: "openai"`。

当缓存的 Gateway 网关探测结果可用时（检查时 Gateway 网关处于健康状态），Doctor 会将其结果与 CLI 可见配置交叉核对，并指出任何差异。Doctor 不会在默认路径上发起新的嵌入探测；如需实时检查提供商，请使用深度记忆状态命令。

使用 `openclaw memory status --deep` 可在运行时验证嵌入就绪状态。

</details>

<details>
<summary>14. 渠道状态警告</summary>

如果 Gateway 网关健康，Doctor 会运行渠道状态探测，并报告警告及建议的修复方法。

</details>

<details>
<summary>15. 监管程序配置审核与修复</summary>

Doctor 会检查已安装的监管程序配置（launchd/systemd/schtasks）是否缺少默认项或使用了过时的默认项（例如 systemd 的 network-online 依赖和重启延迟）。发现不匹配时，它会建议更新，并可将服务文件/任务重写为当前默认值。

注意：

- `openclaw doctor` 会在重写监管程序配置前提示确认。
- `openclaw doctor --yes` 接受默认修复提示。
- `openclaw doctor --fix` 无需提示即可应用建议的修复（`--repair` 是别名）。
- `openclaw doctor --fix --force` 会覆盖自定义监管程序配置。
- `OPENCLAW_SERVICE_REPAIR_POLICY=external` 使 Doctor 对 Gateway 网关服务生命周期保持只读。它仍会报告服务健康状态并运行非服务修复，但会跳过服务安装/启动/重启/引导、监管程序配置重写和旧版服务清理，因为该生命周期由外部监管程序负责。
- 在 Linux 上，当匹配的 systemd Gateway 网关单元处于活动状态时，Doctor 不会重写命令/入口点元数据。在重复服务扫描期间，它还会忽略处于非活动状态且非旧版的其他类似 Gateway 网关的单元，避免配套服务文件产生清理噪声。
- 如果令牌身份验证需要令牌且 `gateway.auth.token` 由 SecretRef 管理，Doctor 在安装/修复服务时会验证 SecretRef，但不会将解析后的明文令牌值持久化到监管程序的服务环境元数据中。
- Doctor 会检测旧版 LaunchAgent、systemd 或 Windows 计划任务安装中内嵌的托管 `.env`/SecretRef 支持的服务环境值，并重写服务元数据，使这些值从运行时来源加载，而不是从监管程序定义加载。
- Doctor 会检测服务命令是否在 `gateway.port` 更改后仍固定使用旧的 `--port`，并将服务元数据重写为当前端口。
- 如果令牌身份验证需要令牌，但配置的令牌 SecretRef 无法解析，Doctor 会阻止安装/修复路径并提供可直接执行的指导。
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`，但未设置 `gateway.auth.mode`，Doctor 会阻止安装/修复，直至显式设置模式。
- 对于 Linux 用户级 systemd 单元，Doctor 在比较服务身份验证元数据时，会在令牌漂移检查中同时包含 `Environment=` 和 `EnvironmentFile=` 来源。
- 如果配置最后由较新版本写入，Doctor 的服务修复将拒绝通过较旧的 OpenClaw 二进制文件重写、停止或重启 Gateway 网关服务。请参阅 [Gateway 网关故障排除](https://funcoding.ai/agents/openclaw/gateway/troubleshooting/#split-brain-installs-and-newer-config-guard)。
- 你始终可以通过 `openclaw gateway install --force` 强制执行完整重写。

</details>

<details>
<summary>16. Gateway 网关运行时与端口诊断</summary>

Doctor 会检查服务运行时（PID、上次退出状态），并在服务已安装但实际未运行时发出警告。它还会检查 Gateway 网关端口（默认 `18789`）上的端口冲突，并报告可能的原因（Gateway 网关已在运行、SSH 隧道）。

</details>

<details>
<summary>17. Gateway 网关运行时最佳实践</summary>

当 Gateway 网关服务在 Bun 或版本管理器管理的 Node 路径（`nvm`、`fnm`、`volta`、`asdf` 等）上运行时，Doctor 会发出警告。Bun 无法打开 OpenClaw 的 `node:sqlite` 状态存储，因此修复流程会将旧版 Bun 服务迁移到 Node。版本管理器路径可能在升级后失效，因为服务不会加载 shell 初始化文件。当系统 Node 安装可用时（Homebrew/apt/choco），Doctor 会提议迁移到该安装。

新安装或修复的 macOS LaunchAgent 使用规范的系统 PATH（`/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin`），而不是复制交互式 shell 的 PATH，因此由 Homebrew 管理的系统二进制文件仍然可用，同时 Volta、asdf、fnm、pnpm 和其他版本管理器目录不会改变 Node 子进程所解析的版本。Linux 服务仍会保留显式环境根目录（`NVM_DIR`、`FNM_DIR`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`BUN_INSTALL`、`PNPM_HOME`）和稳定的用户二进制目录，但推测出的版本管理器后备目录仅在磁盘上确实存在时才会写入服务 PATH。

</details>

<details>
<summary>18. 配置写入与向导元数据</summary>

Doctor 会持久化所有配置更改，并写入向导元数据以记录本次 Doctor 运行。

</details>

<details>
<summary>19. 工作区提示（备份与记忆系统）</summary>

如果缺少工作区记忆系统，Doctor 会建议配置该系统；如果工作区尚未纳入 git 管理，则会输出备份提示。

有关工作区结构和 git 备份的完整指南，请参阅 [/concepts/agent-workspace](https://funcoding.ai/agents/openclaw/concepts/agent-workspace/)（建议使用私有 GitHub 或 GitLab 仓库）。

</details>

## 相关内容

- [Gateway 网关运行手册](https://funcoding.ai/agents/openclaw/gateway/)
- [Gateway 网关故障排除](https://funcoding.ai/agents/openclaw/gateway/troubleshooting/)
