# Dépannage

Cette page part d'un symptôme (une construction qui échoue, un déploiement refusé, une erreur de l'API) et mène à sa cause réelle et à son remède. Elle s'appuie sur les codes que la plateforme renvoie : chacun nomme une cause, l'endroit où corriger et l'action suivante.

## Où lire la cause

Un déploiement en échec porte, dans l'écran **Déploiement** de la console (et dans **Première mise en ligne** pour le premier), une carte « Pourquoi il a échoué ». Elle tient toujours trois lignes :

- la **cause**, en une phrase, propre à la classe d'échec ;
- **Pour ce déploiement**, ce que la plateforme a relevé de cet échec-ci quand elle en dit plus : un code de sortie, un état de nœud, une date ;
- **Où** corriger, puis **À faire**.

Une dernière ligne dit qui corrige : « le dépôt » (votre code ou votre configuration) ou « la plateforme » (relancez ; si l'échec persiste, il ne vient pas de vous). Quand la correction se fait dans la console, un bouton y mène : « Ouvrir les variables », ou « Corriger … dans les paramètres ». Le texte que votre dépôt a écrit (la sortie de la commande qui a échoué) s'affiche à part, dans son propre cadre : c'est le dépôt qui parle, pas la plateforme.

Par un agent, le détail se lit par `deployment_read` (champs `failureCatalog` et `failureReason`) et le journal par `deployment_log_read`.

Quand la plateforme n'a pas classé l'échec, la carte le dit : lisez le journal de construction, puis redéployez. Si l'échec revient à l'identique, signalez-le en citant l'identifiant du déploiement.

## Lire une erreur de l'API

Toute erreur de l'API, de la ligne de commande et des outils MCP a la même forme :

```json
{
  "code": "plafond_de_depense_atteint",
  "message": "…ce qu'il faut faire, en une phrase…",
  "cause": { "fr": "…", "en": "…" },
  "champ": [],
  "suite": { "genre": "aucune", "raison": "…" }
}
```

- `code` est stable : branchez votre comportement dessus, jamais sur le message.
- `champ` nomme les champs en faute, jamais la valeur reçue.
- `suite` dit l'appel suivant : un outil et ses arguments (`outil`), la même demande à reprendre, corrigée ou non (`reprendre`), ou aucune, avec sa raison (`aucune`).

Une 500 (`internal_error`) est journalisée : citez l'identifiant de requête du détail au support.

## Une construction échoue

Commencez par la carte « Pourquoi il a échoué », puis par le journal. Les causes les plus fréquentes, dans l'ordre où elles surviennent :

1. **La récupération du code.** `fetch_failed` : le plus souvent, un dépôt GitHub privé auquel la plateforme n'a pas accès ; installez l'application GitHub en cochant ce dépôt, puis relancez. `reference_introuvable` : la branche ou le commit demandé n'existe pas.
2. **La déclaration du dépôt.** `declaration_refusee` : `glowsoft.json` est invalide, ou déclare plus de services ou de tâches que le palier n'en permet. `controles_refuses` : `.bastide/controles.yaml` est illisible.
3. **Les variables.** `variables_requises_manquantes` : le `.env.example` du dépôt déclare des variables absentes de l'environnement. Le plus simple est « Importer un .env » dans **Variables**.
4. **La détection.** `framework_not_detected` : rien n'est reconnu à la racine de construction ; fournissez un `Dockerfile` ou corrigez le répertoire racine du projet.
5. **Les dépendances.** `dependances_en_conflit`, `installation_des_dependances`, `build_verrou_desynchronise` : le manifeste ou le verrou est à corriger, puis à versionner.
6. **Votre code.** `script_de_construction` : une étape de votre construction a rendu un code non nul. `commande_introuvable` (sortie 127) : un outil appelé n'est pas déclaré parmi les dépendances.
7. **Les bornes.** `build_limite_duree`, `build_limite_memoire`, `build_limite_disque`, `build_limite_journal`, `build_limite_taille` : la construction a dépassé ce que le palier accorde.

Avec votre propre `Dockerfile`, la plateforme refuse avant de construire une instruction qu'elle ne sert pas, en citant la ligne : `# syntax=`, `VOLUME`, `ONBUILD`, `ADD` distant, un registre hors liste, une option privilégiée de `RUN`. Voir [Constructions](builds.md).

## La production refuse une image vulnérable

Après la construction, l'image est analysée. Deux cas bloquent la promotion en production ; les environnements de prévisualisation se déploient comme avant :

- `image_vulnerabilite_exploitee` : une vulnérabilité figure au catalogue des vulnérabilités activement exploitées. Aucune dérogation ne lève ce refus.
- `image_vulnerabilite_critique` : une vulnérabilité de score CVSS 9,0 ou plus, qu'aucune dérogation en vigueur ne couvre.

Mettez à jour le paquet nommé à sa version corrigée, le plus souvent en reconstruisant sur une image de base plus récente, puis redéployez. Le rapport d'analyse et l'inventaire sont attachés à l'image. Une variable d'image qui a la forme d'un secret connu bloque aussi la production (`image_variable_de_secret`) : révoquez d'abord la valeur chez son émetteur, car elle est publiée dans une couche de l'image.

## Plus aucune construction ne part

Deux plafonds arrêtent les constructions sans jamais toucher les sites en ligne :

- `plafond_de_depense_atteint` : la dépense de l'organisation a atteint son plafond pour le cycle. Deux personnes habilitées le relèvent depuis **Facturation**, ou le cycle suivant rouvre les constructions.
- `quota_de_construction_atteint` : le projet a consommé ses minutes de construction du mois. Elles reviennent le premier du mois suivant (UTC) ; une montée de palier les augmente tout de suite. Pour le projet gratuit, le code est `quota_gratuit_construction`.

Voir [Facturation](billing.md) et [Limites par palier](limits.md).

## Le déploiement ne passe pas en production

`controles_non_satisfaits` : des contrôles obligatoires déclarés pour la production ne sont pas satisfaits ; la version en ligne ne change pas. Lisez l'état des contrôles du déploiement (`deployment_list`), corrigez ce qui échoue, puis redéployez. Seule une personne peut passer outre, avec un motif qui reste à l'audit ; un agent reçoit `contournement_reserve`. Voir [Contrôles](checks.md).

## L'application ne démarre pas, ou ne répond pas

La construction a réussi, mais la charge ne devient pas saine :

- `sonde_sans_reponse` : le conteneur tourne, l'application ne répond pas à la sonde dans le délai. Vérifiez qu'elle écoute sur `0.0.0.0` et sur le port de la variable `PORT`. Avec votre propre `Dockerfile`, le port vaut 3000 sauf déclaration de `port` dans `glowsoft.json` ; un `EXPOSE` ne suffit pas. Si l'application démarre lentement, déclarez `probe.startupBudgetSeconds`, et le chemin de la sonde par `probe.path`.
- `redemarrage_en_boucle` : l'application sort ou plante au démarrage, au moins trois fois. Les dernières lignes du journal jointes au déploiement montrent l'erreur : souvent une variable absente ou une base injoignable.
- `memoire_depassee` : le noyau a tué la charge au plafond mémoire du palier. Le rapport porte la valeur observée et la limite.
- `release_sans_port` : la release a été construite sans port relevé ; redéployez depuis la référence Git.

Le système de fichiers est en lecture seule, sauf `/tmp` : une application qui écrit ailleurs échoue au démarrage. Voir [Migrer depuis un VPS](from-vps.md) pour le contrat d'exécution complet.

## Le domaine reste « en attente »

Un domaine n'est servi qu'une fois sa preuve lue dans le DNS.

1. Relisez les enregistrements rendus par `domain.add` (ou **Domaines**) : un TXT de preuve, puis A et AAAA pour un apex, ou un CNAME pour un sous-domaine.
2. Le jeton TXT vaut sept jours. Rappeler `domain.add` sur un domaine en attente rend le même jeton et relit le DNS aussitôt.
3. `domaine_deja_servi` : un autre projet sert déjà ce domaine ; retirez-le de cet autre projet d'abord. `domaine_reserve` : le nom est sous une zone de la plateforme, il ne se rattache pas. `projet_non_revendique` : un projet créé par un agent doit être revendiqué par une personne avant de recevoir un domaine.

Voir [Domaines](domains.md).

## Trop de requêtes : 429

`rate_limited` : le jeton a épuisé une limite de débit sur la fenêtre écoulée. Chaque jeton a 600 appels par minute, et 60 par minute pour les écritures et les lectures de secrets. Attendez le nombre de secondes de `Retry-After`, puis reprenez ; lisez `RateLimit-Remaining` pour ralentir avant le refus. `trop_de_tentatives` : cinq échecs de connexion en quinze minutes ; l'attente double à chaque nouvel échec. `plafond_de_creations_de_projet` : un agent a créé cinq projets dans la journée glissante.

## Les 30 codes les plus utiles

| Code | Statut | Cause | Que faire |
| --- | --- | --- | --- |
| `invalid_request` | 400 | Un champ est absent, mal formé ou contradictoire | Corriger les champs que nomme `champ`, puis reprendre |
| `unauthenticated` | 401 | Jeton absent ou invalide | Se reconnecter (`bastide login`) ou frapper un nouveau jeton |
| `insufficient_rank` | 403 | Rang insuffisant sur ce périmètre | Demander le rang à un administrateur |
| `token_scope_missing` | 403 | Le jeton ne porte pas la portée requise | Créer un jeton qui la porte |
| `agent_action_forbidden` | 403 | Geste réservé à une personne | Le faire depuis la console ou l'API, sous son compte |
| `second_factor_required` | 403 | Un second facteur est exigé | Enrôler une application ou une clé d'accès dans **Compte** |
| `validation_humaine_requise` | 403 | Une opération irréversible se valide par une personne | La valider depuis un compte personnel |
| `not_found` | 404 | Cible introuvable ou hors de votre périmètre | Reprendre l'identifiant d'une réponse précédente |
| `conflict` | 409 | La demande contredit l'état courant | Relire l'état, puis reprendre |
| `confirmation_requise` | 428 | Opération irréversible, en deux temps | Reprendre avec le nonce rendu (cinq minutes) |
| `nonce_expire` | 400 | Le nonce a plus de cinq minutes | Refaire le premier temps |
| `rate_limited` | 429 | Limite de débit atteinte | Attendre `Retry-After` |
| `internal_error` | 500 | Erreur interne, journalisée | Citer l'identifiant de requête au support |
| `timeout` | 503 | Temps dépassé, sans effet | Reprendre sous la même clé d'idempotence |
| `backend_indisponible` | 503 | La base du projet n'est pas joignable | Redéployer si le backend n'était pas prêt ; sinon, le support |
| `quota_exceeded` | 409 | Plafond de variables (1 000) ou d'octets atteint | Supprimer ou réduire des variables |
| `plafond_de_depense_atteint` | 409 | Plafond de dépense du cycle atteint | Relever à deux personnes, ou attendre le cycle |
| `quota_de_construction_atteint` | 409 | Minutes du mois consommées | Attendre le 1er du mois, ou monter de palier |
| `controles_non_satisfaits` | 409 | Contrôles obligatoires non satisfaits | Corriger, puis redéployer |
| `rien_a_restaurer` | 409 | Aucune release précédente restaurable | Lister par `deployment_restorable_list` |
| `domaine_deja_servi` | 409 | Domaine servi par un autre projet | Le retirer de l'autre projet |
| `fetch_failed` | échec | Git n'a pas pu récupérer le code | Installer l'application GitHub sur le dépôt, ou corriger l'adresse |
| `declaration_refusee` | échec | `glowsoft.json` invalide ou au-delà du palier | Corriger le fichier sur la branche par défaut |
| `variables_requises_manquantes` | échec | Variables du `.env.example` absentes | « Importer un .env » dans **Variables** |
| `framework_not_detected` | échec | Rien n'est reconnu à la racine | Fournir un `Dockerfile`, ou corriger la racine du projet |
| `script_de_construction` | échec | Une étape de construction a échoué | Lire la sortie de la commande au journal |
| `image_vulnerabilite_critique` | échec | Vulnérabilité critique sans dérogation | Mettre à jour le paquet nommé, puis redéployer |
| `sonde_sans_reponse` | échec | L'application ne répond pas à la sonde | Écouter sur `0.0.0.0:$PORT`, déclarer `port` et `probe` |
| `redemarrage_en_boucle` | échec | L'application plante au démarrage | Lire les dernières lignes du journal |
| `memoire_depassee` | échec | Plafond mémoire du palier dépassé | Réduire l'empreinte, ou monter de palier |

« échec » désigne une cause inscrite sur un déploiement en échec, et non une réponse HTTP. La liste complète des codes de l'API est publiée avec chaque opération dans la [référence de l'API](../reference/api.md).

## Signaler un problème

Si rien ici ne correspond, écrivez au support en citant l'identifiant du déploiement (`dep_…`) ou l'identifiant de requête de l'erreur, et le code reçu. Ne collez jamais la valeur d'un secret.

Voir aussi : [Déployer](deploy.md), [Constructions](builds.md), [Journaux](logs.md), [Limites par palier](limits.md), [Questions fréquentes](faq.md).
