故障排查
某个东西不工作时,先跑 doctor。它能在一次往返中抓出绝大多数问题。
此外,这里是最常见的失败模式和应对方式。
“没有 espctl 工具可用” / “无法启动 MCP 服务”
你的客户端连 MCP 服务都生不起来。
检查:
- 客户端配置里
espctl的绝对路径对吗?跑ls -l /path/to/espctl确认。 - 它有执行权限吗?没有就
chmod +x。 - 在终端手动跑
espctl mcp serve。它在 stderr 输出了什么?常见问题:cannot find store at <path>—— store 不存在或权限错。- 动态链接器错误 —— 二进制是用比你系统更新的 libc 编译的;从源码 重建或者拿其他发布版。
- 特别针对 macOS 的 Claude Desktop:GUI 应用不继承你 shell 的环境
变量。在
claude_desktop_config.json里明确列出每个环境变量,而 不是依赖~/.zshrc。
doctor 报 control_plane: error
你的 MCP 服务跑得很好,但联系不上构建服务器。
检查:
curl ${CONTROL_BASE_URL}/health—— 它返回 200 加 JSON body 吗?CONTROL_BASE_URL真的是个 URL 吗?常见错误:缺http://或https://scheme、有尾斜杠、或者粘了 SSH 别名而不是可路由的 hostname。- DNS ——
dig或nslookup主机。如果失败,你可能需要用 IP 形式 (http://<你的服务器IP>),直到 DNS 能解析。 - 防火墙 —— 出站 80/443 端口必须能从你机器访问。
doctor 报 control_plane: ok 但构建仍然失败
MCP 服务能联系到构建服务器,但构建没产生输出。
检查:
-
MCP_AUTH_SECRET设了而且对吗?构建需要它;doctor只需要构建 服务器对/health有响应。没有 secret,你会在对/grant/request的响应里看到 “401 Unauthorized”。 -
从构建服务器主机拿到实时 secret:
安全提示: 此命令会显示敏感的鉴权 token。只有运维应该运行它。 永远不要公开分享输出。
ssh <control-host> 'grep -E "^(MCP_AUTH_SECRET|AGENT_AUTH_SECRET)=" /etc/aegis/secrets.env /etc/aegis/control.env 2>/dev/null' -
至少有一台构建机器在线吗?运维可以用
aegis-control list-agents(或者读构建服务器的 metrics)检查。 -
构建机器和构建服务器时钟同步吗?许可有短 TTL;如果任何一边的时钟 相差超过 ~30 秒,每个许可在能用之前就过期了。
WebRTC 连接建立后立即关闭
on_open 触发了但连接几秒后断开,或者 on_open 永远没触发。
可能原因:
- 连接协商失败。 没有候选对工作。peer 连接状态在 ~5 秒后到
Failed,数据通道永远不打开。原因:网络限制或防火墙屏蔽所有 UDP 而备选服务器没配置或不可达。 - 两侧都有网络限制。 直接点对点不可能;强制通过备选服务器中继。
确保构建服务器在
ice_servers里至少返回一个中继条目。 - 中继凭据过期。 中继凭据按会话轮换;如果你的客户端从早期 会话缓存了一个,它已经失效。打开新会话。
- 浏览器屏蔽了 WebRTC。 一些公司浏览器策略完全禁用 WebRTC。
Chrome 上检查
chrome://webrtc-internals/看连接候选 dump。
修复模式: 客户端总应该实现一个快速失败,在等待 on_open 的
同时监视 RTCPeerConnection.connectionState === 'failed'。把
connect() 包在一个 3 次尝试的重试循环里,每次之间间隔 2 秒。
构建在 pending 状态挂很久
许可颁发了,但没有构建机器接任务。
检查:
- 构建机器在线吗?闲置构建服务器可以颁发许可,但没有构建机器响应时,
任务会挂在
pending直到超时。 - 构建机器有能力跑请求的 target 吗?如果你要
esp32p4但没构建机器装 了那个工具链,任务会挂着不被分配。运维可以在构建服务器日志看到未 分配的任务。
构建编译错误失败
这是简单情况。问你的 AI 助手:
对最近的构建跑
parse_build_errors,然后对结果跑diagnose-build-error提示。
你会得到结构化的“哪里错了、为什么、这是修法“,而不是 500 行日志。
“通道 pty 被拒绝”
构建机器拒绝打开一个不在许可白名单里的数据通道。
原因: 你客户端的许可请求没在 required_channels 里包含
pty。这通常发生在客户端升级到一个使用新通道的版本,但运维还没
更新构建服务器的允许通道列表。
修复: 要么更新构建服务器的允许列表,要么把客户端 pin 到一个不用 新通道的版本。
发送队列满 / 固件下载停滞
固件下载吞吐量在中途显著下降(只在大 *.bin 文件经过中继连接时
重要)。
原因: 生产构建机器把发送队列上限设为 128 KB。结合 500 ms 往返 延迟的中继连接,这把吞吐量限制在 ~256 KB/s,而不是你在直连点对点 上看到的多 MB/s。
修复: 这是有意的(防止反压下的内存耗尽)。如果你的固件大到这 重要,优先用直连点对点而不是中继。直连不那么严重地受队列上限影响, 因为往返时间低得多。
“部署前 CORS 错误”
你是构建服务器运维,浏览器连 /grant/request 都到不了。
检查:
cat /etc/aegis/control.env | grep ALLOWED_ORIGINS—— 你的 origin 在里面吗?- 值包含 scheme(
https://)且不带尾斜杠吗?ALLOWED_ORIGINS=https://esphome.cloud是对的;ALLOWED_ORIGINS=esphome.cloud/不对。 - 你编辑 env 文件后重启
aegis-control了吗?sudo systemctl restart aegis-control。
还是卡住
- 让你的 AI 助手读
install://overview资源 —— 它返回 MCP 服务内部 看到的同样的环境变量表,可以让你比对服务认为它的配置是什么。 - 看实时日志:构建服务器(
journalctl -u aegis-control -f)、构建 机器(journalctl -u aegis-agent -f)。 - 在 aegis 或 type-driven-ui 仓库提 issue,附上
doctor的输出。