Dépannage
Cette page regroupe les erreurs les plus courantes, leur cause et leur résolution. Si votre cas n'y figure pas, ouvrez une issue sur DiamondForgeFr/SaasFoundryAI.
Commencez par le diagnostic local
Exécutez sf status --no-network dans le projet. La commande affiche le manifeste, les modules installés et les préconditions que le CLI vérifie avant d'agir.
docker compose up : réseau saasfoundry-network introuvable
Symptôme
ERROR: Network saasfoundry-network declared as external, but could not be found.Cause — Les projets générés rejoignent un réseau Docker externe commun à l'API, la base et éventuellement MinIO. Le fichier Compose ne crée pas ce réseau.
Correction
docker network create saasfoundry-network
docker compose upCette création n'est nécessaire qu'une fois par machine.
npm install refuse la version de Node ou npm
Symptôme
npm warn EBADENGINE Unsupported engineCause — Le CLI et les projets générés n'ont pas exactement la même version cible :
- le dépôt du CLI exige Node
>=22.0.0, npm>=10.0.0, et son.nvmrcfixe actuellement Node22.15.0; - les applications générées demandent Node
24.19.0, car elles imposent npm 11.
Utilisez toujours le .nvmrc du dépôt dans lequel vous vous trouvez.
Correction
nvm install
nvm use
node --version
npm --versionNe forcez pas une installation contre devEngines : les builds et les commandes du projet continueront à refuser une version incompatible.
.saasfoundry.json est invalide
Symptôme
✗ Manifest .saasfoundry.json failed schema validation
/modules/email — must be one of: { "provider": "mailersend", … }, "none"Cause — Chaque commande valide le manifeste avec AJV et schemas/saasfoundry-manifest.schema.json. Une faute de clé, une ancienne forme ou une édition manuelle incompatible échoue immédiatement.
Correction
- Repérez le chemin JSON indiqué, par exemple
/modules/email. - Comparez la valeur au schéma livré avec la même version du CLI.
- Si le manifeste provient d'une ancienne version, exécutez
sf updateafin d'appliquer les migrations enregistrées.
Votre éditeur peut utiliser :
{
"$schema": "https://raw.githubusercontent.com/DiamondForgeFr/SaasFoundryAI/develop/schemas/saasfoundry-manifest.schema.json"
}Le validateur n'invente aucune correction ; il désigne le champ à réparer.
sf update crée des fichiers *.saasfoundry.new
Symptôme
⚠ Conflict: file modified locally and in template — wrote new version to <path>.saasfoundry.newCause — Votre projet et le template ont modifié le même fichier. Le merge à trois voies préserve votre version et écrit la proposition à côté au lieu de l'écraser.
Correction
diff <file> <file>.saasfoundry.new
# Intégrez les changements voulus dans <file>, vérifiez-les, puis :
rm <file>.saasfoundry.newLe sidecar ne réapparaîtra que si une nouvelle évolution du template rencontre encore un fichier localement modifié.
Port déjà utilisé — 3000, 5173 ou 5435
Symptôme
Error: listen EADDRINUSE: address already in use 0.0.0.0:3000Cause — Un autre processus ou conteneur occupe le port. sf new choisit désormais le prochain port libre lorsqu'aucune valeur explicite n'est demandée et l'enregistre dans ports du manifeste. Le problème concerne surtout un projet déjà généré dont le port a été pris ensuite.
Correction
lsof -i :3000 # ou :5173, :5435
kill <pid>
docker ps
docker stop <name>Pour remapper, modifiez la variable PORT de l'API, server.port du frontend ou le mapping de docker-compose.db.yml, puis gardez .saasfoundry.json → ports cohérent. À la génération, --db-port, --api-port et --web-port imposent un port ou échouent ; ils ne sont jamais déplacés silencieusement.
Échec d'un hook Husky
Symptômes
⧗ input: feat: my feature
✖ scope may not be empty [scope-empty]ou la vérification de formatage en lecture seule échoue sur l'index Git.
Contrôles
| Hook | Contrôle |
|---|---|
commit-msg | commitlint : <type>(#<ticket>): <description> |
pre-commit | npm run test:staged, validation ciblée et en lecture seule de l'index Git |
pre-push | cohérence RC/tag et vérifications WIP ; les cycles Docker sont lancés explicitement pendant AI testing |
Correction
- Utilisez un message comme
feat(#317): calibrate SRS intent detector. - Si Prettier signale un écart, exécutez
npm run format, inspectez et indexez les modifications, puis relancez le commit. Le hook ne réécrit pas les fichiers. - Corrigez les erreurs ESLint ou TypeScript, puis recommencez.
- N'utilisez pas
--no-verifypour contourner une erreur ordinaire.
gh n'est pas authentifié
Symptôme
✗ gh CLI not authenticated. Run: gh auth loginCause — L'adaptateur GitHub Projects s'appuie sur le CLI officiel pour lire et modifier le tableau.
Correction
gh auth login
gh auth statusAvec plusieurs comptes, utilisez gh auth switch. Les tokens sous ~/.config/gh/ ne doivent jamais être versionnés.
SRS : srs-cli.sh validate retourne 5
Symptôme
✗ Notion adapter init failed (network or auth)
exit 5Cause — L'adaptateur Notion n'atteint pas la page configurée avec le token fourni.
Correction
- Vérifiez le token dans
~/.claude/credentials/notion/<account>.env; il doit commencer parsecret_et ne pas être un placeholder. - Partagez explicitement la page
tools.srs.rootPage.urlavec l'intégration Notion. - Vérifiez la sortie HTTPS vers
api.notion.com. - Si les identifiants sont corrects mais la configuration de page obsolète, reconfigurez le module ou l'outil SRS par la commande correspondant à votre version du CLI ; ne modifiez pas les fichiers de compétence à la main.
Notion couvre la SRS v1. Il ne remplace pas l'adaptateur GitHub Projects pour le cycle complet des tickets.
npm run test:docker dépasse son délai
Symptôme
Lifecycle: new-monorepo-full
============================================================
Lifecycle deadline exceeded after 1800sCause — Un cycle effectue une vraie génération ou mise à jour, les installations, les builds de production, le démarrage API/Web, les parcours navigateur et les assertions PostgreSQL. Le scénario possède un budget interne de 30 minutes ; la CI conserve 40 minutes afin de collecter le teardown et les diagnostics.
Correction
npm run test:docker:scenario -- new-monorepo --depth full
npm run test:docker:list -- --lane normalConsultez les artefacts lifecycle-timing-* et les diagnostics d'échec. Les voies stables sont déclarées dans tests/docker/ci-lanes.ts et exécutées par tests/docker/generate-and-build.ts.
Un échec de teardown ou un test instable doit être signalé avec ses artefacts ; une simple relance réussie ne suffit pas à le faire disparaître du rapport.
La CI et le poste local n'utilisent pas la même version de Node
Symptôme — Les tests locaux passent, mais GitHub Actions échoue sur TypeScript ou le build.
Cause — Les workflows fixent une version majeure via actions/setup-node, tandis que .nvmrc fixe la version de développement du dépôt. Les cycles générés peuvent aussi utiliser Node 24 alors que les jobs du CLI utilisent Node 22.
Correction
- Inspectez tous les blocs
actions/setup-nodedans.github/workflows/. - Comparez-les au
.nvmrcdu dépôt concerné et à la matrice du job. - Reproduisez localement avec la même version que le job en échec.
- Mettez à jour la CI ou la configuration locale selon le contrat intentionnel ; n'alignez pas mécaniquement CLI et projets générés, qui peuvent cibler des versions différentes.
Le drift guard échoue après une modification de compétence
Symptôme
FAIL src/__tests__/integration/skill/<name>-drift.spec.ts
expected file content to be byte-equalCause — Les compétences sont dogfoodées. Leur source sous scaffolds/skills-templates/ et leur dépôt local sous .claude/skills/ doivent rester identiques lorsqu'ils ne sont pas reliés par un symlink.
Correction
# Modifiez d'abord la source, puis synchronisez le dépôt local attendu :
cp scaffolds/skills-templates/<name>/<file> .claude/skills/<name>/<file>
npx jest src/__tests__/integration/skill/<name>-drift.spec.ts --no-coverageRespectez les chemins exacts indiqués par le test : pendant la transition multi-agents, certaines sources sont également déposées sous .agents/skills/ et protégées par le manifeste.
Pour aller plus loin
- Commandes —
sf new,sf update,sf workflow,sf skill - Workflow — Compétences principales
- SRS — Tutoriel SRS
- Défaut non couvert — joignez les sorties de
sf status --no-networketsf --versionà l'issue