Écrits

Ce qui bloque Claude Code lors de son premier lancement en conteneur

Un agent Claude Code neuf dans un conteneur s’arrête successivement sur trois invites : l’onboarding, la validation de confiance du dossier et la clé API. Chacune attend une réponse interactive sur un terminal sans opérateur humain, et se résout en injectant la configuration adéquate avant le lancement.

Un agent qui démarre, affiche une bannière et attend produit des octets. Dans un journal de logs, cela ressemble à un succès. Pourtant, dans un conteneur vierge, Claude Code s’arrête trois fois avant tout travail utile, attendant des réponses sur un terminal sans opérateur.

Three gates in a row. An agent passes the first two and stops at the third.onboardingtrustapi keya fresh container
L’ordre est déterminant. Un agent ayant validé les deux premières étapes reste bloqué à la troisième.

Les trois étapes bloquantes dans l’ordre d’apparition

ÉtapeQuestion posée
Assistant de premier lancementChoix du thème graphique
Vérification de confiance du workspaceFaites-vous confiance à ce projet ?
Validation de la clé d’APIVoulez-vous utiliser cette clé d’API ?

La première et la troisième sont globales à la machine. La deuxième est enregistrée par dossier. Résoudre deux étapes sur trois donne l’illusion d’avancer mais bloque toujours le lancement.

Résultats des mesures empiriques

Chaque ligne ci-dessous a été mesurée avec claude 2.1.220 sur un vrai pty dans un HOME vierge :

Configuration injectéeComportement observé
AucuneBloqué sur le sélecteur de thème
theme dans settings.json seulToujours bloqué sur le sélecteur de thème
hasCompletedOnboarding dans .claude.jsonAtteint le dialogue de confiance
+ hasTrustDialogAccepted sur le projet résoluAtteint l’invite avec « Not logged in »
+ ANTHROPIC_API_KEY dans l’environnementBloqué sur « Do you want to use this API key? »
+ customApiKeyResponses.approvedAtteint l’invite fonctionnelle « API Usage Billing »

Le piège du chemin résolu

L’état de confiance s’enregistre dans ~/.claude.json sous projects[chemin], où le chemin doit être canonique. Sur macOS, mkdtempSync produit /var/folders/… alors que le chemin résolu est /private/var/folders/…. Injecter le chemin non résolu écrit une clé ignorée par le binaire et le dialogue réapparaît.

export function trustKeyFor(root: string): string {
  try {
    return realpathSync(root);
  } catch {
    return root;
  }
}

La validation de clé API

Le piège de la confirmation de clé API est que son choix par défaut est 2. No (recommended). Le CLI n’enregistre pas la clé entière, mais seulement ses vingt derniers caractères sous forme d’empreinte d’approbation.

export function approvalTokenFor(apiKey: string): string {
  return apiKey.slice(-20);
}

Deux fausses pistes

L’option --permission-mode bypassPermissions ne débloque pas le dialogue de confiance initial : elle concerne uniquement les permissions d’outils. De même, injecter un chemin non résolu échoue systématiquement.

Un thème n’est pas un choix critique. Supprimer un fichier en est un.

Pré-valider la confiance d’un dossier est légitime puisque notre plateforme en est l’instigatrice. En revanche, nous ne court-circuitons pas les autorisations d’outils sensibles en cours de session :

const trust: ProjectTrust = {
  hasTrustDialogAccepted: true,
  hasCompletedProjectOnboarding: true,
  projectOnboardingSeenCount: 0,
  allowedTools: [],
};

Recommandations pour automatiser les lancements d’agents

Testez l’état de l’invite de commande et non le simple flux d’octets sortant. Pilotez vos processus via un pty réel et inspectez les fichiers de configuration produits par le CLI.

L’exécution de Claude Code dans notre environnement cloud est abordée dans Claude Code dans le navigateur, et la résilience du flux dans observer un terminal distant.

Réponses directes

Pourquoi Claude Code se fige-t-il au premier lancement dans un conteneur ?

Il ne se fige pas : il attend des réponses interactives (choix du thème, confiance dans le répertoire et confirmation de la clé API). Sans opérateur humain devant le terminal, l’exécution n’aboutit jamais.

Comment exécuter Claude Code de façon non interactive ?

En pré-remplissant son fichier de configuration (~/.claude.json) avec les états d’onboarding et de confiance du projet, et en fournissant les identifiants via l’environnement.

Comment ces données ont-elles été mesurées ?

Sur un véritable pty avec la version 2.1.220 du binaire Claude Code, en inspectant directement les structures JSON générées.