Voltar para a documentação
Guia 12

Troubleshooting

Sintomas comuns, causa, resolução. Referências file:line e cross-link para os docs.

6 min de leitura

Sintomas comuns, causa, resolução. Referências file:line e cross-link para os docs.

Arranque & config

O servidor sai imediatamente com process.exit(1)

  • Causa: validação env Zod falhada (src/config/env.ts).
  • Fix: revê os logs - indicam a variável inválida. Verifica JWT_SECRET (obrig.), COLLECTOR_SECRET (obrig.), DATABASE_URL, portas. Compara com .env.example.

COLLECTOR_SECRET mismatch entre server e collector

  • Sintoma: o collector não consegue notificar o status do documento; o upload fica "processing".
  • Fix: define o mesmo COLLECTOR_SECRET no .env raiz (config única - a camada .env per-package foi removida na v0.22). Comparação constant-time → erro 401 silencioso.

WIDGET_API_KEY mismatch widget↔server

  • Sintoma: o widget não carrega config / chat 401 do servidor.
  • Fix: mesma key no .env raiz (config única). Sem key, o cache-bust push é no-op (TTL 5 min).

Config modificada pela UI sem efeito

  • Causa: as chaves ALWAYS_READONLY (JWT_SECRET, DATABASE_URL, portas, URL) são rejeitadas pelo bulk settings; as restantes seguem DB > ENV > Default.
  • Fix: para chaves readonly, modifica .env + restart. PUT /api/system/settings devolve { rejected: [...] } - revê esse array.

Database

Migrações em conflito / reset dev

  • Fix: em dev com DB descartável, reset com pnpm db:migrate:reset:guard (requer PRISMA_MIGRATE_RESET_CONFIRM=yes ou --force-accept-data-loss - nunca em produção). Deploy com guard: pnpm db:migrate:guard (rejeita migrações destrutivas sem consentimento explícito). Verifica PostgreSQL 16 e DATABASE_URL correta.

Restore backup não atómico / dados parciais

  • Causa: o restore usa psql --single-transaction --set ON_ERROR_STOP=on; se falhar faz rollback completo.
  • Fix: revê os logs psql; safety backup pre-restore (runSafetyBackup). Usa /restore/:logId/dry-run antes do restore real.

RAG & embedding

Vector search devolve 0 resultados mas FTS funciona

  • Causa: guard D-01 - EMBEDDING_MODEL atual ≠ embeddingModel dos Document (p. ex. modelo mudado após upload): o leg vector é saltado e a busca degrada para FTS-only.
  • Fix: re-embed via POST /api/system/reembed-documents (admin, opcional workspaceId/documentIds) para re-embeddear os chunks com o modelo atual; se só precisas de reconstruir o índice FTS a partir do vector DB: POST /api/system/reindex-documents. Ambos admin-only, também em Settings → Maintenance.

RAG degradado no widget (status: rag-degraded)

  • Causa: pre-search RAG falhada (collector down, whitelist workspace vazia) ou 0 resultados da busca dos workspace vinculados.
  • Fix: verifica GET /api/health/rag; revê WidgetWorkspace para o widget (GET /api/widgets/:id/workspaces); confirma collector up (GET :3210/api/health).

LanceDB table missing / query error

  • Causa: tabela per-workspace ws_<name>_<shortId> não criada ou storage movido.
  • Fix: verifica que o STORAGE_PATH do collector está inalterado; reindex wiki/documentos.

Agent & LLM

Agent abort: unknown_tool_breaker

  • Causa: circuit breaker BOT-03 - 3 skills desconhecidas consecutivas / 5 no total. Muitas vezes um modelo que alucina tools não registados.
  • Fix: usa um modelo mais capaz ou reduz as skills habilitadas; verifica a conexão MCP enabled e as skills registadas (mcp_<conn>_<tool>).

Agent abort: wallclock / token_budget / context_overflow

  • Fix: sobe os env AGENT_WALLCLOCK_TIMEOUT_MS (default 600000), AGENT_MAX_TOTAL_TOKENS (200000), AGENT_MAX_CONTEXT_BYTES (500000). Para tarefas simples baixa para evitar stalls. Ver 03 - Configuration § Agent watchdog.

Modelo não responde / timeout LLM local

  • Causa: Ollama down ou modelo não puxado; LLM_TIMEOUT=0 = sem timeout (LLM locais lentos).
  • Fix: ollama list / ollama pull gemma4:latest; verifica OLLAMA_BASE_URL (http://ollama:11434 no compose). Fallback provider: revê Provider.isAvailable (polling 30s).

Fallback provider não disparado

  • Causa: nenhum provider alternativo disponível (isAvailable=false) ou default global não definido.
  • Fix: adiciona provider (POST /api/providers), set default (PUT /:id/set-default), verifica o tag deriveCapabilities. Frontend fallback 3-tier com toast Undo.

Widget

O widget não carrega / iframe vazio

  • Causa: allowedOrigins não inclui a origem host → CORS dinâmico fail-closed.
  • Fix: adiciona a origem a Widget.allowedOrigins (string CSV, max 2000 char). Verifica que GET /api/config/:widgetId responde.

Lead capture 403

  • Causa: config.leadCaptureEnabled=false para esse widget.
  • Fix: habilita no modelo Widget (admin UI ou API).

Rate limit 429 no widget

  • Causa: cadeia de limiter - widgetDailyMessageLimiter (5/24h por widget+IP, override sessionLimitPerDay), widgetChatLimiter (30/min por widgetId, override rateLimitPerMinute), widgetSessionLimiter (50 criações de sessão/dia por IP), widgetLeadLimiter (3/h por IP).
  • Fix: avalia os overrides per-widget (rateLimitPerMinute/sessionLimitPerDay); revê qual limiter disparou (header Retry-After / body error).

MCP

Instalação marketplace 201 mas tools não disponíveis

  • Causa: connectMCPServer é fire-and-forget; a falha é logada mas não propagada.
  • Fix: POST /api/mcp-connections/:id/test (10s, devolve {success, toolCount, error}). Verifica o transport fallback D-09; revê activeConnections via GET /api/mcp-connections/statuses.

MCP desabilitado automaticamente

  • Causa: auto-disable estilo webhook? Não - a conexão MCP permanece enabled; é o webhook que se auto-desabilita após 10 falhas consecutivas. Para MCP, o health check 30-min define healthStatus (stale/down) mas não desabilita a conexão.
  • Fix: para o webhook, reativa manualmente; para MCP, o badge health é informativo.

Tool MCP não usado numa chat

  • Causa: pin per-chat ativos que excluem a conexão, ou conexão disabled.
  • Fix: GET /api/chats/:chatId/pins; verifica resolveSkillsForChat (sem pin → todas as conexões enabled do workspace).

Licença

402 Payment Required numa feature

  • Causa: requireFeature(flag) ou requireFeatureLimit gateou (Community).
  • Fix: define LICENSE_KEY Enterprise, ou fica no Community com os limites. O body error inclui feature, tier, limit?, current?.

Enterprise expirado em runtime

  • Comportamento: graceful degradation para Community (sem restart); warn nos logs.
  • Fix: renova LICENSE_KEY; getLicenseInfo() relê em runtime.

Segurança & audit

Audit log não escreve

  • Causa: o audit log é um módulo Enterprise - no Community logEvent é um no-op (o delegado de escrita não está registado), portanto nenhum evento é registado.
  • Fix: Enterprise para audit log + imutabilidade (audit_log_immutable). Verifica o entityType correto nos filtros (GET /api/event-logs). Os webhooks de evento saem na mesma no Community (fire-and-forget).

DLP não redige PII

  • Causa: DLP_ENABLED=false via settings (o default na v0.22 é "true" - alguém desativou), ou um role em DLP_BYPASS_ROLES que o isenta do scan.
  • Fix: verifica/define DLP_ENABLED=true via settings. Redaction sobre 10 padrões built-in database-backed: os 6 originais (email, credit_card, ssn, api_key, aws_key, private_key) mais os 4 EU/IT (it_vat_iva, it_codice_fiscale, iban, eu_phone - este último seedado DISABLED para review admin); padrões custom até 50 via o painel DLP Patterns. SSE done → dlp_matches (o frontend mostra a DLPNotice sob a mensagem).

Backup

Job backup fica "running" para sempre

  • Causa: worker morto sem cleanup; mutex DB BackupLog.status="running".
  • Fix: cleanStaleLocks marca running >2h como failed no próximo bootstrap. Reinicia o servidor para o trigger, ou atualiza manualmente o status.

Checksum mismatch no restore

  • Causa: arquivo corrompido / upload parcial.
  • Fix: SHA-256 streaming calculado no upload; verifica o ficheiro destino. Restaura do log seguinte.

Discrepâncias documentais conhecidas

Doc dizCódigo dizFonte de verdade
"28 permissions" / "27"31 permissões (PERMISSION_NAMES)código
"12 menu sections"13 (MENU_SECTIONS, +uploads)código
"7" languages i18n8 app locales (en, it, ru, de, fr, es, zh, pt)i18n/locales/
API-key auth (esquema antigo)HMAC-SHA256 sk- keys (key_hash + API_KEY_HMAC_SECRET)services/apiKeyService.ts
--profile enterprise composenão definido explicitamenteLICENSE_KEY ativa Enterprise

Health check rápido

bash
curl localhost:3000/api/health        # { database, collector, disk }
curl localhost:3000/api/health/rag    # estado RAG
curl localhost:3210/api/health        # collector
curl localhost:3211/health            # widget