Troubleshooting
Troubleshooting
Dernière mise à jour : 2026-05-10
Pièges connus déjà rencontrés, à actualiser au fil des incidents.
Build / CI
Le job test échoue avec une erreur better-sqlite3
- Cause : tu as changé l'image de base CI vers Alpine. Pas de prebuild musl pour
better-sqlite3. - Fix : remettre
node:22-bookworm-slim(Debian Slim glibc).
vue-tsc --noEmit passe en local mais foire en CI
- Cause : la CI fait
vue-tsc --build(compile full), pas--noEmit(type-check seul). - Fix : tester avec
npm run build(qui appellevue-tsc --build) avant de push.
Backend runtime
Boolean("false") === true — env var qui ne fait pas ce qu'on attend
- Symptôme :
VISION_ENABLED=falseest interprété commetrue. - Cause :
z.coerce.boolean()en JS — toute chaîne non vide est truthy. - Fix : utiliser le helper
envBool()défini en haut desrc/config.ts. Comprendtrue/false/1/0/yes/no/on/off.
process.env.X retourne undefined en prod
- Cause : la var n'a pas été ajoutée dans
unraid/boardgame-referee.xml, donc l'admin Unraid ne l'a pas setée dans l'UI. - Fix : règle des 3 fichiers —
src/config.ts+.env.example+unraid/boardgame-referee.xml. Sinon la var est silencieusement absente.
Une regex \b ne match pas un nom finissant par é
- Cause :
\bsans flagune reconnaît que les boundaries[A-Za-z0-9_]. - Fix : lookahead Unicode-aware avec flag
u:(?=\\s|$|[^\\p{L}\\p{N}_]). Piège historiquement déclenché sur les mentions@Lorcana.
Claude répond "je ne vois aucune image"
- Cause :
claude-ssh.tslance le CLI avec--system-promptau lieu de--append-system-prompt. Le contrat d'utilisation des outils est écrasé. - Fix : toujours
--append-system-prompt.
ClaudeQuotaError non détectée → "answer empty" générique
- Cause : le wording du message de quota a changé côté Anthropic.
- Fix : étendre
QUOTA_MARKERSdansclaude-quota.ts. Cf.pipeline-rag/pause-quota-claude.md.
Retrieval / RAG
Citation [BASE p.4 : "..."] ouvre la mauvaise page
- Cause : plusieurs livrets indexés partagent la page 4 (base + extension). La regex de citation ne capturait pas le nom du livret.
- Fix : cf. ARCHITECTURE.md § "Citations cliquables — format nom du livret". Le format est désormais
[<nom du livret>, p.X : "..."]avec résolutionnameToIdcôté frontend.
Image PNG envoyée à Claude mais c'est la page 4 du mauvais livret
- Cause : groupage par
pageau lieu de(livret, page)dansanswer.ts. - Fix : cf.
pipeline-rag/vision-inline.md— granularité composite obligatoire.
Claude cite un livret en [EXT p.4] au lieu de [Heavy Rain, p.4]
- Cause : ancien format de citation pré-2026-04-11.
- Fix : c'est rétrocompatible côté frontend (regex avec fallback). Mais à terme migrer le SYSTEM_PROMPT pour imposer le nouveau format.
Reranker retourne ~0 sur du contenu technique abstrait → enterre le bon chunk
- Cause : le reranker bge-v2-m3 est peu confiant sur du jargon technique.
- Fix : c'est précisément la motivation du blending position-aware (RAG Fusion v2). Cf. ADR-005. Si tu vois encore des cas, considérer ajuster les ratios (
75/25→85/15sur top-3).
Frontend
display: flex dans une CSS scoped écrase le hidden lg:flex Tailwind
- Cause : la spécificité CSS scoped batt utilities.
- Fix : préférer Tailwind utilities partout. Si tu dois absolument scoped, utiliser
!importantou@apply.
Card autocomplete @ ne matche pas un nom japonais / accentué
- Cause :
\bregex Unicode-incompatible (cf. backend ci-dessus, même piège). - Fix :
useArbiterMarkdown.ts:74-81— lookahead(?=\\s|$|[^\\p{L}\\p{N}_])avec flagu.
CardZoomModal ne s'ouvre pas après reload
- Cause :
cardLookupn'a pas été reconstruit depuis les messages persistés en localStorage. - Fix :
usePlaySessionappellerebuildFromMessages()on mount. Vérifier que ce path n'a pas été cassé.
SSE casse à 60s pile et UI affiche network error
- Cause : NPM
proxy_read_timeout 60s+ heartbeat backend pas émis. - Fix : vérifier que
setIntervalheartbeat 8s est bien armé dans le service streamSSE. Pattern dansroutes/ask.ts.
Infra
TEI répond 000 (curl no response)
- Cause : port custom Unraid (8099 au lieu de 80, 8990 au lieu de 8090).
- Fix : suspecter d'abord le port. Cf. mémoire
reference_unraid_ports.md.
Container oracle SSH timeout
- Cause : VM oracle down ou auth ed25519 cassée.
- Fix :
ssh -i /app/ssh/id_ed25519 oracle@<host> "cd /home/oracle/work && claude -p" <<< "test"- Si timeout : SSH server down, restart la VM
- Si
Permission denied: vérifierauthorized_keyscôté VM, vérifier que la clé privée n'a pas été régénérée
Wrapper oracle rejette toutes les commandes
- Cause : préfixe strict du wrapper modifié sans aligner les autres endroits.
- Fix : 3 endroits doivent matcher (
/home/oracle/bin/oracle-claude.shPREFIX,CLAUDE_SSH_WORKDIRenv,permissions.allow/additionalDirectoriesdu settings.json oracle). Cf.securite/ssh-oracle.md.
Logs spam "EADDRINUSE :::3000"
- Cause : container restart trop rapide, l'ancien process pas encore mort.
- Fix :
docker compose down && docker compose up -d(au lieu de restart).
BDD
Migration Drizzle qui ne s'applique pas
- Cause :
drizzle-kit generaten'a pas détecté le diff (rare). Ou la table__drizzle_migrations__est désynchronisée. - Fix : vérifier le contenu de
migrations/vssrc/schema.ts. Si nécessaire,npm run db:migratemanuel pour forcer.
database.db is locked
- Cause : un autre process / container tient le fichier.
- Fix :
lsof /app/data/database.db(depuis Unraid CLI) pour identifier. Souvent un ancien container qui n'est pas vraiment mort.
No comments to display
No comments to display