常见症状、原因、解决方案。file:line 引用和 docs 交叉链接。
启动与 config
服务器立即以 process.exit(1) 退出
- 原因:env Zod 校验失败(
src/config/env.ts)。 - 修复:检查日志 - 会指出无效变量。验证
JWT_SECRET(必填)、COLLECTOR_SECRET(必填)、DATABASE_URL、端口。与.env.example对照。
server 与 collector 之间 COLLECTOR_SECRET 不匹配
- 症状:collector 无法通知文档状态;上传一直停留在 "processing"。
- 修复:在根
.env中设置相同的COLLECTOR_SECRET(单一 config - per-package 的.env层已在 v0.22 移除)。constant-time 比较 → 静默 401 错误。
widget↔server 之间 WIDGET_API_KEY 不匹配
- 症状:widget 不加载 config / 从服务器返回 chat 401。
- 修复:根
.env中相同的 key(单一 config)。没有 key 时,cache-bust push 为 no-op(TTL 5 min)。
从 UI 修改的 config 无效
- 原因:
ALWAYS_READONLY键(JWT_SECRET、DATABASE_URL、端口、URL)被 bulk settings 拒绝;其他键遵循DB > ENV > Default。 - 修复:对于 readonly 键,修改
.env+ restart。PUT /api/system/settings返回{ rejected: [...] }- 检查该数组。
Database
迁移冲突 / dev reset
- 修复:在使用一次性 DB 的 dev 中,用
pnpm db:migrate:reset:guardreset(需要PRISMA_MIGRATE_RESET_CONFIRM=yes或--force-accept-data-loss- 绝不在生产环境)。带 guard 的 deploy:pnpm db:migrate:guard(未经明确同意拒绝破坏性迁移)。验证 PostgreSQL 16 和正确的DATABASE_URL。
Restore backup 非原子 / 数据部分丢失
- 原因:restore 使用
psql --single-transaction --set ON_ERROR_STOP=on;失败时执行完整 rollback。 - 修复:检查 psql 日志;safety backup pre-restore(
runSafetyBackup)。真实 restore 前使用/restore/:logId/dry-run。
RAG 与 embedding
Vector search 返回 0 结果但 FTS 正常
- 原因:guard D-01 - 当前
EMBEDDING_MODEL≠Document的embeddingModel(例如上传后更换模型):vector leg 被跳过,搜索降级为 FTS-only。 - 修复:通过
POST /api/system/reembed-documents(admin,可选workspaceId/documentIds)用当前模型重新 embed chunk;如果只需从 vector DB 重建 FTS 索引:POST /api/system/reindex-documents。两者都是 admin-only,也可从 Settings → Maintenance 操作。
widget 中 RAG 降级(status: rag-degraded)
- 原因:RAG pre-search 失败(collector down、workspace whitelist 为空)或链接 workspace 的搜索 0 结果。
- 修复:验证
GET /api/health/rag;检查 widget 的WidgetWorkspace(GET /api/widgets/:id/workspaces);确认 collector up(GET :3210/api/health)。
LanceDB table missing / query error
- 原因:per-workspace 表
ws_<name>_<shortId>未创建或 storage 被移动。 - 修复:验证 collector 的
STORAGE_PATH未变;reindex wiki/文档。
Agent 与 LLM
Agent abort:unknown_tool_breaker
- 原因:circuit breaker BOT-03 - 连续 3 个未知 skill / 累计 5 个。通常是模型幻觉出未注册的 tool。
- 修复:使用更强的模型或减少启用的 skill;验证 MCP connection enabled 和已注册的 skill(
mcp_<conn>_<tool>)。
Agent abort:wallclock / token_budget / context_overflow
- 修复:调高 env
AGENT_WALLCLOCK_TIMEOUT_MS(默认 600000)、AGENT_MAX_TOTAL_TOKENS(200000)、AGENT_MAX_CONTEXT_BYTES(500000)。对于简单任务调低以避免 stall。见 03 - Configuration § Agent watchdog。
模型无响应 / 本地 LLM 超时
- 原因:Ollama down 或模型未拉取;
LLM_TIMEOUT=0= 无超时(本地 LLM 较慢)。 - 修复:
ollama list/ollama pull gemma4:latest;验证OLLAMA_BASE_URL(compose 中为http://ollama:11434)。Fallback provider:检查Provider.isAvailable(30s polling)。
Fallback provider 未触发
- 原因:没有可用的替代 provider(
isAvailable=false)或未设置全局 default。 - 修复:添加 provider(
POST /api/providers)、set default(PUT /:id/set-default)、检查deriveCapabilities标签。Frontend fallback 3-tier 带 toast Undo。
Widget
widget 不加载 / iframe 为空
- 原因:
allowedOrigins不包含 host origin → 动态 CORS fail-closed。 - 修复:将 origin 添加到
Widget.allowedOrigins(CSV 字符串,最多 2000 字符)。验证GET /api/config/:widgetId有响应。
Lead capture 403
- 原因:该 widget 的
config.leadCaptureEnabled=false。 - 修复:在
Widget模型中启用(admin UI 或 API)。
widget 上 rate limit 429
- 原因:limiter 链 - widgetDailyMessageLimiter(per widget+IP 5/24h,override
sessionLimitPerDay)、widgetChatLimiter(per widgetId 30/min,overriderateLimitPerMinute)、widgetSessionLimiter(per IP 每天 50 次会话创建)、widgetLeadLimiter(per IP 3/h)。 - 修复:评估 per-widget override(rateLimitPerMinute/sessionLimitPerDay);检查触发了哪个 limiter(header
Retry-After/ bodyerror)。
MCP
marketplace 安装 201 但 tool 不可用
- 原因:
connectMCPServer是 fire-and-forget;失败只记录日志,不传播。 - 修复:
POST /api/mcp-connections/:id/test(10s,返回{success, toolCount, error})。验证 transport fallback D-09;通过GET /api/mcp-connections/statuses检查activeConnections。
MCP 被自动禁用
- 原因:webhook 风格的 auto-disable?不是 - MCP connection 保持 enabled;是 webhook 在连续 10 次失败后自动禁用。对于 MCP,30-min health check 设置
healthStatus(stale/down)但不会禁用连接。 - 修复:对于 webhook,手动重新启用;对于 MCP,health badge 仅供参考。
MCP tool 在某个 chat 中未被使用
- 原因:活跃的 per-chat pin 排除了该连接,或连接 disabled。
- 修复:
GET /api/chats/:chatId/pins;验证resolveSkillsForChat(无 pin → workspace 中所有 enabled 连接)。
许可证
某个 feature 出现 402 Payment Required
- 原因:
requireFeature(flag)或requireFeatureLimit触发了 gating(Community)。 - 修复:设置 Enterprise
LICENSE_KEY,或以 Community 的限制继续。Error body 包含feature、tier、limit?、current?。
Enterprise 在运行时过期
- 行为:graceful degradation 到 Community(无需 restart);日志中有 warn。
- 修复:续期
LICENSE_KEY;getLicenseInfo()在运行时重新读取。
安全与 audit
Audit log 不写入
- 原因:audit log 是 Enterprise 模块 - 在 Community 中
logEvent是 no-op(write delegate 未注册),因此不会记录任何事件。 - 修复:Enterprise 以启用 audit log + immutability(
audit_log_immutable)。在过滤器中验证正确的entityType(GET /api/event-logs)。事件 webhook 在 Community 中仍会发出(fire-and-forget)。
DLP 不 redact PII
- 原因:通过 settings 设置
DLP_ENABLED=false(v0.22 中默认是"true"- 有人禁用了它),或角色在DLP_BYPASS_ROLES中豁免了 scan。 - 修复:通过 settings 验证/设置
DLP_ENABLED=true。对 10 个内置 database-backed pattern 进行 redaction:6 个原始 pattern(email、credit_card、ssn、api_key、aws_key、private_key)加上 4 个 EU/IT(it_vat_iva、it_codice_fiscale、iban、eu_phone- 后者 seed 为 DISABLED 待 admin review);通过 DLP Patterns 面板最多 50 个自定义 pattern。SSEdone→dlp_matches(前端在消息下显示 DLPNotice)。
Backup
Backup job 永远停留在 "running"
- 原因:worker 死亡且未 cleanup;DB mutex
BackupLog.status="running"。 - 修复:
cleanStaleLocks在下次 bootstrap 时将 running >2h 标记为 failed。重启服务器以触发它,或手动更新 status。
Restore 时 checksum mismatch
- 原因:归档损坏 / 上传部分丢失。
- 修复:上传时计算 SHA-256 streaming;验证目标文件。从下一个 log 恢复。
已知文档差异
| 文档说 | 代码说 | 真相来源 |
|---|---|---|
| "28 permissions" / "27" | 31 个权限(PERMISSION_NAMES) | 代码 |
| "12 menu sections" | 13(MENU_SECTIONS,+uploads) | 代码 |
| "7" languages i18n | 8 个 app locale(en、it、ru、de、fr、es、zh、pt) | i18n/locales/ |
| API-key auth(旧 schema) | HMAC-SHA256 sk- keys(key_hash + API_KEY_HMAC_SECRET) | services/apiKeyService.ts |
--profile enterprise compose | 未明确定义 | LICENSE_KEY 激活 Enterprise |
快速 health check
bash
curl localhost:3000/api/health # { database, collector, disk }
curl localhost:3000/api/health/rag # RAG 状态
curl localhost:3210/api/health # collector
curl localhost:3211/health # widget交叉链接
- Config/env:03 - Configuration
- Internals:05 - Feature Guide
- Deploy:09 - Deployment