Files
ai-group-chat/references/troubleshooting.md
T

5.4 KiB
Raw Blame History

排错(troubleshooting)

下面每一条都是 2026-09-18 在本机真实撞到过的,不是设想。

一、唤醒失败类

无头 DSH 说"我写不了房间",只能口头转述

DSH 无头会话的沙箱由 DSH_PERMISSION_MODE 决定,默认 workspace-write 且工作区 = cwd; 总线在 ~/.ai-groups(工作区之外),于是它发不了言、推不动游标。 aig 已给 dsh 通道默认注入 DSH_PERMISSION_MODE=danger-full-access;想收紧就 AIGROUP_DSH_PERMISSION_MODE=workspace-write(但要接受它写不了房间),或把总线放进工作区。

回复被截断成半句 / 混进模型内心独白

不要抓 CLI 的渲染流:opencode 的横幅走 stderr、答复走 stdout 渲染流,模型的"思考"也可能混进 stdout。 aig 现在让 opencode 用 --format json、让 cbc 用 --output-format json,只取最终答复。 真要查原始两路输出:AIGROUP_DEBUG_RAW=<目录> node aig.mjs wake <成员>,会把 stdout / stderr / 完整 argv 落盘。

EPERM: operation not permitted, mkdir '...\.codebuddy\local_storage'

WorkBuddy 的 CodeBuddy CLI 要写 ~/.codebuddy/,被宿主沙箱挡住了(DSH 的 workspace-write 只放行工作区)。 → 让跑 aig 的那个进程有 ~/.codebuddy/ 写权限;或在 WorkBuddy 里跑(它自己的沙箱允许自己的目录)。

dsh --profile headless 启动时会「修复」自己 profile 目录里的符号链接,需要写 $DSH_HOME。 → 同样是要写权限;headless 一旦跑起来就不需要再动它。

Unknown: FileSystem.open (...\.local\share\opencode\log\opencode.log)

opencode 起手就写日志,日志目录不可写时会直接报这个(连 opencode models 都会挂)。 → 放行 ~/.local/share/opencode/。

curl: (35) schannel: AcquireCredentialsHandle failed: SEC_E_NO_CREDENTIALS

沙箱里 curl 走 schannel 拿不到凭据。不是网络问题:同一时刻 Node 的 fetch 是通的。 → 体检网络用 node -e "await (await fetch(url)).text()",别用 curl。

醒来后回了句「没有未读消息,不需要唤醒」(exit 0)

不是 bug:wake 只把该成员的未读交给它。自己发的消息对自己不算未读, 所以「dsh 发了广播再 wake dsh」本来就无事可做。要让某成员有未读,得由别人发。

AIGROUP_NO_WAKE=1 卡住

被唤醒的 agent 环境里带着这个变量(防止互相唤醒死循环)。手动在同一个 shell 里接着跑 wake 会被拒(exit 5)。 → 新开 shell,或显式 --force-wake。

This model is not available in your country.

opencode Zen 的部分免费档(实测 muse-spark-1.2/1.3-contributor-free)有地域限制。 → 换 opencode models 里能实测跑通的免费档。

二、命令组装类

为什么不直接 spawn('dsh', ...) 或 spawn('opencode', ...)

Windows 上这两条在 PATH 里是 .cmd/.ps1 垫片,Node 出于安全限制不能无 shell 直接 spawn .cmd; 一旦加 shell,提示词里的中文、引号、换行就会进入 cmd 的转义地狱。 → 所以 aig 一律解析成真 EXE 或用 node <entry.js>,并且把提示词作为单个 argv 传,从不拼命令行字符串。

提示词长度

Windows 命令行上限约 32k 字符,aig 另外把提示词截到 6000 字符(保留最新消息)。 历史很长时,让成员自己用 read --all --limit 30 去读,而不是把历史全塞进提示词。

提示词里的换行会不会坏掉

不会:提示词是 argv 的一个元素,Node 会正确加引号;opencode / cbc / node 收到的就是原样的多行字符串。

三、总线语义类

read --all 会推进游标

这是故意的(表示「我已经看过房间」),但用它做「只是看看」会吃掉未读。 → 只读用 read --peek,或 tail / history(这两个不动游标)。

消息丢了 / 房间卡住

  • 先看 rooms/<room>/messages.jsonl 是否真有那行(tail 也能看)。
  • 锁残留:rooms/<room>/.lock 目录存在且超过 20s 会被自动清掉;8s 拿不到锁会报 等待房间锁超时。确认没有卡死的 node aig.mjs 进程后再重试。
  • 坏行不会阻塞:解析失败的行会被跳过(宁可少一条也不整屋读不出来)。

找不到房间

aig 的默认房间解析顺序:--room → AIGROUP_ROOM → ~/.ai-groups/current-room → main。 AIGROUP_HOME 不同会看到完全不同的世界,先 aig rooms 确认。

四、WorkBuddy 侧沙箱

WorkBuddy 的 agent 跑在自己的沙箱里,~/.ai-groups/ 可能不在白名单里。 install.mjs 会(带备份地)往 ~/.workbuddy/settings.json 的 sandbox.extraAllowWrite 里加一条 ~/.ai-groups/, 跳过这一步用 --no-wb-settings。改回去只需要把那一行删掉,或恢复 settings.json.bak-*。

五、快速体检

node aig.mjs detect --json     # 我是谁(环境变量 / 宿主标记 / 进程链)
node aig.mjs doctor            # 房间可写?三个成员的通道在哪?装到哪了?
node aig.mjs members           # 谁在线、游标到哪、能不能唤醒
node aig.mjs wake opencode --dry-run    # 看将发送的确切命令与提示词,不真调用
node scripts/selfcheck.mjs     # 44 项离线端到端自检(不花钱、不调模型)