Happy CLI 启动异常的排查尝试记录
文章目录
前言
最近OpenClaw很火,个人感觉体验其实一般,没什么质的飞跃,核心还是自己配skill和各种工具,真要算就是加上了远程控制。
我认为 Happy + Claude Code 就足够了,但之前能启动的Happy最近死活启动不成功。
于是有了本文,本文内容是AI的尝试和AI总结,本人润色优化,仅作记录。

Happy是一个 monorepo 项目,包含:
happy-cli:终端侧happy-app:移动端happy-server:服务端
我最开始是通过 npm install -g happy-coder安装的 CLI。一开始启动完全正常,但使用一段时间后,本地启动开始
反复报错,而且有时候报错还不一致。
想着借助AI来定位修复看看,经过反复的调试,修复了多个看起来"像 bug"的问题,但都无济于事,最后发现是 Happy 的使用方式搞错了。
第一层问题:CLI 启动直接崩溃
最开始的报错非常简单:
Cannot read properties of undefined (reading 'id')
有时候甚至只打印:
Error
定位过程
顺着堆栈追到:
packages/happy-cli/src/api/api.ts
问题代码类似这样:
| |
如果服务端返回:
HTTP 200
但响应结构缺失:
| |
代码就会直接触发:
Cannot read properties of undefined (reading 'id')
这属于典型的 缺少防御性校验。
修复方案
AI在几个关键位置增加了校验。
1. getOrCreateSession
| |
避免直接访问:
undefined.id
2. getOrCreateMachine
同样增加校验:
| |
3. API Client 构造函数
防止非法对象继续流入系统:
| |
修复效果
这样即使服务端返回异常数据结构:
- CLI 不会直接崩溃
- 能输出日志用于排查
看起来问题解决了。
但实际上 只是刚开始。
第二层问题:机器注册失败并误判离线
修完第一轮错误后,CLI 可以启动了。
但日志开始出现新的问题:
Machine registration failed: invalid_response
Server returned success but response missing machine.id
接着 CLI 会把服务器标记为:
offline
实际情况
服务端其实返回了:
HTTP 200
只是响应 body 不符合 CLI 的结构预期。
也就是说:
服务端成功了,但 CLI 误判失败。
修复思路
原代码在这里调用:
| |
这会导致客户端认为服务器不可达。
AI改成:
只记录日志,不标记失败。
| |
这样:
- 不影响后续 session 创建
- CLI 仍继续运行
第三层问题:Remote Mode React Hook 报错
解决上面的问题后,CLI 可以进入 Remote Mode。
但新的错误又出现了:
Invalid hook call
Cannot read properties of null (reading 'useState')
这类报错通常只会出现在一种情况:
React 实例不一致
原因分析
Happy CLI UI 是基于:
inkreact
而 CLI bundle 内部又打包了一份 React。
结果运行时出现:
ink -> React A
CLI bundle -> React B
React hook dispatcher 只挂在:
React A
但组件调用的是:
React B.useState()
于是就变成:
null.useState
修复方案
强制 CLI 使用 ink 的 React 实例。
在 launcher 中:
| |
然后渲染 UI:
| |
在组件内部:
| |
所有 hooks 都从传入的 React 获取。
这样整棵组件树只使用 一个 React 实例。
Hook 报错消失。
第四层问题:CLI 与 App 消息通信异常
再往后,看似是正常了,但实际还是不可用:
happy-cli 能收到 happy-app 的消息
但:
CLI 发出的消息是否到达 app 不确定
于是AI在发送路径增加了日志,例如:
Sending envelope
Flushed N message(s)
flushOutbox failed
从日志看:
CLI -> server
POST 请求基本成功
偶尔失败也会自动重试。
但:
app 端仍然收不到消息
后续经过反复的尝试,我发现偶尔又能通过已经构建好的Cli成功启动。
最终发现:问题其实不在代码
修了这么多代码后,我开始意识到一个问题:
为什么 Happy 一开始是能正常运行的?
于是重新检查使用方式。
最后发现问题其实非常简单:
我用错了 Happy 的运行模式。
Happy 的正确使用方式
Happy CLI 不是设计成在多个目录分别运行的。
正确流程是:
1 初始化绑定
| |
2 程序后台启动守护进程
| |
3 APP 通过守护进程创建 session

而不是:
| |
这样会产生:
多个 CLI 实例
多个 session
多个 machine 注册
导致状态混乱。
如果需要重新初始化环境,可以删除:~/.happy/,重新绑定。
总结
瞎折腾半天也没有成功,但好在结果是好的,也不枉费一番尝试。
从 Claude Code 的出现开始,越来越直观地感受到 AI 的迭代速度,如何更好的将 AI 融入日常工作中,提升效率,需要持续的探索。