故障排查

本文列出 Wesclaw 常见问题的诊断与修复方法。


Go 后端启动失败

症状

排查步骤

  1. 查看日志

    macOS: ~/Library/Application Support/wesclaw/logs/
    Linux: ~/.local/share/wesclaw/logs/
    
  2. 初始化配置(首次使用)

    wesclaw init
    # 编辑 config.yaml,填入 LLM Provider API Key
    
  3. 检查数据目录权限 — 确保 XDG DataDir 有完整读写权限

  4. 引擎版本 — boot 日志应输出 sdk_version,若缺失说明启动未完成


Electron 更新超时

症状

原因与修复

autoUpdater.quitAndInstall() 的 forceRunAfter 超时应设为 10s(而非 3s),给 Go 后端留出安全关闭窗口。

机制说明
handleShutdown同步执行 StopEngine + CloseStore,RPC 返回时资源已释放
INV-RESIL-04Cell 进程排他锁(flock .cell.lock),防止重复写入
Boot 降级即使数据损坏,Boot 返回 nil error(降级合法),不阻塞启动

wesclaw.db 迁移失败

症状

机制(INV-MIGRATE-01)

wesclaw.db 使用 PRAGMA user_version 驱动迁移链:

Boot → 读 user_version → 按序执行未应用的 MigrationStep
→ 每步一个事务(DDL + version 递增)→ 全部成功 → DB 可用

降级策略:迁移失败 → 归档旧文件为 .migration-failed → 清除 WAL/SHM → 全新 DB → 重跑迁移 → 二次失败才 fatal。

三链共存

wesclaw.db 上运行三条独立迁移链,互不干扰:

链策略管理的表
Chain 1 store.RunMigrationsPRAGMA user_versiontc_conversations 等 8 表
Chain 2 group.Migrate()IF NOT EXISTS + 列检测tc_groups 等 4 表
Chain 3 auth.Migrate()IF NOT EXISTS + DEV-1tc_session

Cell 锁竞争

症状

原因

同一 Cell 同一时刻只允许一个写入者(flock .cell.lock,INV-RESIL-04)。

解决

  1. 确认是否有残余 wesclaw 进程仍在运行
  2. macOS:ps aux | grep wesclaw;Linux:同理
  3. 杀掉残余进程后重试

SSE 断流

症状

设计(INV-RUN-DETACH)

Run 生命周期与 SSE 连接完全解耦。SSE 断开不会取消 Run。

行为说明
断开后 Run 继续Run 独立于传输层运行
重连续播GET /runs/{runID}/events?from_seq=N
终止手段POST /sessions/{sid}/interrupt(用户主动)

chatInFlight 锁

同一时刻最多一个可见生成轮次,锁在 done/error/interrupted 事件到达时释放:

发送 → 加锁 → 流式响应 → 终端事件 → 释放锁

若卡住:使用 interrupt 端点中断当前 Run。


IM 渠道收不到消息

排查步骤

  1. Webhook URL 格式

    每个 Cell 使用独立 URL:

    POST /cells/{cellID}/webhook/wecom
    POST /cells/{cellID}/webhook/feishu
    POST /cells/{cellID}/webhook/dingtalk
    
  2. 预检验证

    POST /cells/{cellID}/channels/preflight
    
  3. 检查渠道配置 — GET /cells/{cellID}/channels 确认凭证正确

  4. SeedSpec 注意 — CellSpec.Channels 是出生声明,首次 boot 后存储为权威源


Provider 连接失败

排查步骤

  1. 测试连通性

    POST /cells/{cellID}/providers/test
    {"provider": "my-openai", "mode": ""}
    # mode: 空=chat, "embedding", "vision"
    
  2. SecretRef 来源

    Source说明
    inline明文经 AES-256-GCM 封套后落盘
    env从环境变量读取
    live运行时动态注入(WES/Org)
  3. WES vs BYOK

    • WES 模型依赖平台 JWT,过期后自动失效并 fallback 到 BYOK
    • BYOK 密钥本地存储,不受 WES 状态影响

模型选择器为空

排查步骤

  1. 确认 Provider 已配置 — 至少配置一个可用 Provider(WES 登录或 BYOK)
  2. 检查 Models 声明 — Provider 必须声明 Models[],含 context_window
  3. Catalog 来源 — weisyn.ProviderCatalog()(catalog.yaml)是唯一模型数据源
  4. 前端单一 RPC — sidebar/availableModels 统一返回所有可用模型
  5. 发送条件 — selectedModel == "" 时发送按钮 disabled(INV-MODEL-02)

WES 欠费处理

场景发送提示
WES 欠费 + 有 BYOK + 选 BYOK✅ 正常无
WES 欠费 + 有 BYOK + 选 WES❌ 阻断引导切换 BYOK
WES 欠费 + 无 BYOK❌ 阻断引导充值或配置 BYOK

关键:已选 BYOK 时不得禁用输入或显示"请切换到自有模型"(INV-CHAT-02/04)。


日志位置

日志路径内容
Go 后端$WESCLAW_DATA_DIR/logs/引擎运行日志
Electron$WESCLAW_DATA_DIR/logs/{timestamp}/窗口日志
Chat 管道$WESCLAW_DATA_DIR/logs/wescode-chat.logRPC send/recv + Webview 事件
引擎崩溃$WESCLAW_DATA_DIR/crashes/panic 栈(fd 2 dup2 到文件)

macOS 路径示例:~/Library/Application Support/wesclaw/


版本升级注意事项

  1. 引擎版本只升不降 — 旧引擎读新格式 spec 可能导致 Cell 目录被归档
  2. 升级前备份 — Cell Export 或手动备份 cells/main/ 目录
  3. tc_ 表清空* — 升级到含 cell_id 列的版本时,应用数据会一次性清空
  4. Boot 安全 — 即使迁移失败,Boot 仍会成功(降级模式)
  5. 日志确认 — 升级后检查 sdk_version 日志确认版本正确

快速诊断清单

# 1. Go 后端是否存活
ps aux | grep wesclaw

# 2. 健康检查(桌面版无 HTTP,用 RPC 冒烟)
make rpc-test

# 3. 数据目录检查
ls -la ~/Library/Application\ Support/wesclaw/

# 4. 日志查看
tail -100 ~/Library/Application\ Support/wesclaw/logs/*.log

# 5. 构建检验
go build ./... && go vet ./...
cd apps/desktop/web && npx tsc --noEmit -p tsconfig.app.json