Retour à la documentation
Guide 12

Troubleshooting

Symptômes courants, cause, résolution. Références file:line et cross-link vers les docs.

6 min de lecture

Symptômes courants, cause, résolution. Références file:line et cross-link vers les docs.

Démarrage & config

Le serveur sort immédiatement avec process.exit(1)

  • Cause : validation env Zod échouée (src/config/env.ts).
  • Fix : contrôle les logs - ils indiquent la variable invalide. Vérifie JWT_SECRET (oblig.), COLLECTOR_SECRET (oblig.), DATABASE_URL, les ports. Compare avec .env.example.

COLLECTOR_SECRET mismatch entre server et collector

  • Symptôme : le collector n'arrive pas à notifier le status du document ; l'upload reste "processing".
  • Fix : définis le même COLLECTOR_SECRET dans le .env racine (config unique - la couche .env per-package a été supprimée en v0.22). Comparaison constant-time → erreur 401 silencieuse.

WIDGET_API_KEY mismatch widget↔server

  • Symptôme : le widget ne charge pas la config / chat 401 depuis le serveur.
  • Fix : même key dans le .env racine (config unique). Sans key, le cache-bust push est no-op (TTL 5 min).

Config modifiée depuis l'UI sans effet

  • Cause : les clés ALWAYS_READONLY (JWT_SECRET, DATABASE_URL, ports, URL) sont refusées par le bulk settings ; les autres suivent DB > ENV > Default.
  • Fix : pour les clés readonly, modifie .env + restart. PUT /api/system/settings retourne { rejected: [...] } - contrôle ce tableau.

Database

Migrations en conflit / reset dev

  • Fix : en dev avec DB jetable, reset avec pnpm db:migrate:reset:guard (exige PRISMA_MIGRATE_RESET_CONFIRM=yes ou --force-accept-data-loss - jamais en production). Deploy avec guard : pnpm db:migrate:guard (refuse les migrations destructives sans consentement explicite). Vérifie PostgreSQL 16 et DATABASE_URL correcte.

Restore backup non atomique / données partielles

  • Cause : le restore utilise psql --single-transaction --set ON_ERROR_STOP=on ; s'il échoue il fait un rollback complet.
  • Fix : contrôle les logs psql ; safety backup pre-restore (runSafetyBackup). Utilise /restore/:logId/dry-run avant le restore réel.

RAG & embedding

Vector search retourne 0 résultats mais FTS fonctionne

  • Cause : guard D-01 - EMBEDDING_MODEL actuel ≠ embeddingModel des Document (ex. modèle changé après upload) : le leg vector est sauté et la recherche dégrade en FTS-only.
  • Fix : re-embed via POST /api/system/reembed-documents (admin, optionnel workspaceId/documentIds) pour ré-embedder les chunks avec le modèle courant ; si tu dois seulement reconstruire l'index FTS depuis le vector DB : POST /api/system/reindex-documents. Les deux admin-only, aussi depuis Settings → Maintenance.

RAG dégradé dans le widget (status: rag-degraded)

  • Cause : pre-search RAG échouée (collector down, whitelist workspace vide) ou 0 résultat de la recherche des workspace liés.
  • Fix : vérifie GET /api/health/rag ; contrôle WidgetWorkspace pour le widget (GET /api/widgets/:id/workspaces) ; confirme collector up (GET :3210/api/health).

LanceDB table missing / query error

  • Cause : table per-workspace ws_<name>_<shortId> non créée ou storage déplacé.
  • Fix : vérifie que STORAGE_PATH du collector est inchangé ; reindex wiki/documents.

Agent & LLM

Agent abort : unknown_tool_breaker

  • Cause : circuit breaker BOT-03 - 3 skills inconnues consécutives / 5 au total. Souvent un modèle qui hallucine des tool non enregistrés.
  • Fix : utilise un modèle plus capable ou réduis les skills activées ; vérifie la connexion MCP enabled et les skills enregistrées (mcp_<conn>_<tool>).

Agent abort : wallclock / token_budget / context_overflow

  • Fix : augmente les env AGENT_WALLCLOCK_TIMEOUT_MS (défaut 600000), AGENT_MAX_TOTAL_TOKENS (200000), AGENT_MAX_CONTEXT_BYTES (500000). Pour des tâches simples, baisse pour éviter un stall. Voir 03 - Configuration § Agent watchdog.

Modèle ne répond pas / timeout LLM local

  • Cause : Ollama down ou modèle non pullé ; LLM_TIMEOUT=0 = aucun timeout (LLM locaux lents).
  • Fix : ollama list / ollama pull gemma4:latest ; vérifie OLLAMA_BASE_URL (http://ollama:11434 dans le compose). Fallback provider : contrôle Provider.isAvailable (polling 30s).

Fallback provider non déclenché

  • Cause : aucun provider alternatif disponible (isAvailable=false) ou default global non défini.
  • Fix : ajoute un provider (POST /api/providers), set default (PUT /:id/set-default), vérifie le tag deriveCapabilities. Frontend fallback 3-tier avec toast Undo.

Widget

Le widget ne se charge pas / iframe vide

  • Cause : allowedOrigins n'inclut pas l'origine hôte → CORS dynamique fail-closed.
  • Fix : ajoute l'origine à Widget.allowedOrigins (string CSV, max 2000 char). Vérifie que GET /api/config/:widgetId répond.

Lead capture 403

  • Cause : config.leadCaptureEnabled=false pour ce widget.
  • Fix : active dans le modèle Widget (admin UI ou API).

Rate limit 429 sur le widget

  • Cause : chaîne de limiter - widgetDailyMessageLimiter (5/24h par widget+IP, override sessionLimitPerDay), widgetChatLimiter (30/min par widgetId, override rateLimitPerMinute), widgetSessionLimiter (50 créations de session/jour par IP), widgetLeadLimiter (3/h par IP).
  • Fix : évalue les overrides per-widget (rateLimitPerMinute/sessionLimitPerDay) ; contrôle quel limiter a triggeré (header Retry-After / body error).

MCP

Installation marketplace 201 mais tools non disponibles

  • Cause : connectMCPServer est fire-and-forget ; l'échec est loggé mais non propagé.
  • Fix : POST /api/mcp-connections/:id/test (10s, retourne {success, toolCount, error}). Vérifie le transport fallback D-09 ; contrôle activeConnections via GET /api/mcp-connections/statuses.

MCP désactivé automatiquement

  • Cause : auto-disable style webhook ? Non - la connexion MCP reste enabled ; c'est le webhook qui s'auto-désactive après 10 échecs consécutifs. Pour MCP, le health check 30-min définit healthStatus (stale/down) mais ne désactive pas la connexion.
  • Fix : pour le webhook, réactive manuellement ; pour MCP, le badge health est informatif.

Tool MCP non utilisé dans une chat

  • Cause : pin per-chat actifs qui excluent la connexion, ou connexion disabled.
  • Fix : GET /api/chats/:chatId/pins ; vérifie resolveSkillsForChat (pas de pin → toutes les connexions enabled du workspace).

Licence

402 Payment Required sur une feature

  • Cause : requireFeature(flag) ou requireFeatureLimit a gateé (Community).
  • Fix : définis LICENSE_KEY Enterprise, ou reste sur Community avec les limites. Le body error inclut feature, tier, limit?, current?.

Enterprise expiré à la runtime

  • Comportement : graceful degradation vers Community (pas de restart) ; warn dans les logs.
  • Fix : renouvelle LICENSE_KEY ; getLicenseInfo() relit à la runtime.

Sécurité & audit

Audit log n'écrit pas

  • Cause : l'audit log est un module Enterprise - en Community logEvent est un no-op (le délégué d'écriture n'est pas enregistré), donc aucun événement n'est enregistré.
  • Fix : Enterprise pour l'audit log + l'immutabilité (audit_log_immutable). Vérifie le entityType correct dans les filtres (GET /api/event-logs). Les webhooks d'événement partent quand même en Community (fire-and-forget).

DLP ne rédige pas les PII

  • Cause : DLP_ENABLED=false via settings (le défaut en v0.22 est "true" - quelqu'un l'a désactivé), ou un rôle dans DLP_BYPASS_ROLES qui l'exempte du scan.
  • Fix : vérifie/définis DLP_ENABLED=true via settings. Redaction sur 10 patterns built-in database-backed : les 6 originaux (email, credit_card, ssn, api_key, aws_key, private_key) plus les 4 EU/IT (it_vat_iva, it_codice_fiscale, iban, eu_phone - ce dernier seedé DISABLED pour revue admin) ; patterns custom jusqu'à 50 via le panneau DLP Patterns. SSE done → dlp_matches (le frontend montre la DLPNotice sous le message).

Backup

Job backup reste "running" pour toujours

  • Cause : worker mort sans cleanup ; mutex DB BackupLog.status="running".
  • Fix : cleanStaleLocks marque running >2h comme failed au prochain bootstrap. Redémarre le serveur pour le déclencher, ou mets à jour manuellement le status.

Checksum mismatch au restore

  • Cause : archive corrompue / upload partiel.
  • Fix : SHA-256 streaming calculé à l'upload ; vérifie le fichier de destination. Restaure depuis le log suivant.

Discrepances documentaires connues

Doc ditCode ditSource de vérité
"28 permissions" / "27"31 permissions (PERMISSION_NAMES)code
"12 menu sections"13 (MENU_SECTIONS, +uploads)code
"7" languages i18n8 app locales (en, it, ru, de, fr, es, zh, pt)i18n/locales/
API-key auth (ancien schéma)HMAC-SHA256 sk- keys (key_hash + API_KEY_HMAC_SECRET)services/apiKeyService.ts
--profile enterprise composenon défini explicitementLICENSE_KEY active Enterprise

Health check rapide

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