Claude Code 2.1.246 : ta règle Bash couvre peut-être plus large que son texte
Une seule version depuis la 2.1.245, mais une soixantaine d'entrées. La plus utile tient dans un nouvel avertissement au démarrage : une règle d'autorisation Bash dont l'étoile est placée avant la sous-commande autorise beaucoup plus que ce que tu as écrit. Plus une clé de gateway qui partait chez le mauvais destinataire, et trois cas où le client rapportait un succès à la place d'une interruption.
Une seule version depuis le dernier digest : la 2.1.246, sortie le 25 août. Aucune nouvelle commande, aucun nouveau modèle, une soixantaine de lignes dont l'écrasante majorité sont des correctifs.
Une version de réparation, donc. Sauf que trois de ces correctifs touchent à des choses que tu croyais acquises : la portée réelle de tes règles de permission, la destination de tes secrets, et ce que le client rapporte quand une commande s'interrompt. Voilà le tri.
Une étoile mal placée dans une règle Bash
C'est la seule entrée de la version qui te demande une action, et elle prend la forme d'un avertissement au démarrage sur les règles d'autorisation Bash qui ont une étoile avant la sous-commande, du type Bash(git * main).
Le changelog justifie l'avertissement en une incise : ces règles « correspondent aussi aux options insérées avant la sous-commande ». Formulé comme ça, ça ressemble à une subtilité de syntaxe. La doc sur les motifs à joker est nettement plus directe, et c'est elle qu'il faut lire.
Le principe de correspondance tient en une phrase : Claude Code prend tout ce qui précède la première étoile au pied de la lettre, et ce sont donc ces mots-là, et eux seuls, qui limitent la règle. Dans Bash(git log *), ce qui limite c'est git log. Dans Bash(git * main), ce qui limite c'est git. La règle a beau se terminer par main, elle n'autorise pas « les commandes git qui portent sur main », elle autorise toutes les sous-commandes git, et toutes les options placées avant.
La doc donne la démonstration dans son tableau, et le troisième exemple est le seul qui compte :
| Tu écris | Ça correspond aussi à |
|---|---|
Bash(git * main) | git merge main, git push origin main, git -c core.fsmonitor=<script> diff main |
L'option -c core.fsmonitor= fait exécuter à git un programme que tu nommes. Autrement dit, une règle écrite pour restreindre les permissions à une branche ouvre en réalité l'exécution d'un programme arbitraire, sous couvert de git. La doc le pose noir sur blanc : l'étoile « remplace le texte qui se trouve à sa place », ici la sous-commande, « ce qui inclut -c, qui fait exécuter à git un programme que tu nommes ».
Le correctif est trivial et il est entre tes mains : mets l'étoile après la sous-commande. Bash(git log *), Bash(git commit *), Bash(npm run *). Si tu as besoin de cibler une branche, écris Bash(git log * main) : la sous-commande est nommée, l'étoile ne remplace plus que les options de git log.
Deux remarques pour finir sur ce point. D'abord, ces règles ne viennent pas toutes de toi : le dialogue de permission écrit lui-même une règle quand tu réponds « Oui, et ne me redemande plus », ce qui fait qu'un fichier de réglages accumule des motifs que personne n'a relus. Ensuite, la même version durcit un cas voisin : les vérifications de permission Bash exigent désormais systématiquement une approbation pour les commandes malformées qui laissent un && ou un || en suspens. Le mécanisme derrière est expliqué dans la section sur les commandes composées : Claude Code découpe la commande sur &&, ||, ;, |, |&, & et les retours à la ligne, puis exige qu'une règle corresponde à chaque sous-commande indépendamment. Une commande dont l'analyse laissait un opérateur orphelin passait à côté de ce découpage. Elle demande maintenant confirmation.
Dans la même famille, le mode auto gagne un onglet dédié dans /permissions, pour consulter et modifier les règles de son classifieur (la doc sur les modes de permission détaille quelles actions ce classifieur voit passer). Et les appels d'outil refusés en mode auto avec un « temporarily unavailable » sur les très grosses sessions sont corrigés : le délai de la vérification de sûreté suit maintenant la taille du prompt au lieu d'être fixe.
Ta clé de gateway ne part plus chez Anthropic
Une ligne, glissée au milieu des correctifs, et personne n'y prêtera attention :
Corrigé : les requêtes de télémétrie et de métriques vers Anthropic transportaient la clé API configurée pour un gateway tiers (
ANTHROPIC_BASE_URL). Un identifiant n'est désormais envoyé qu'à son propre hôte.
Il faut dérouler pour voir le problème. Si ton organisation route l'inférence vers un gateway ou un proxy tiers via ANTHROPIC_BASE_URL, la clé que tu configures n'est pas une clé Anthropic : c'est le secret de ton gateway à toi. Or la télémétrie et les métriques, elles, partent bien chez Anthropic. Un secret destiné à un hôte était donc expédié à un autre.
Ce n'est pas une faille exploitable par un tiers, et ça ne concerne que les configurations à gateway. Mais c'est un secret sorti de son périmètre, et le changelog ne dit ni depuis quelle version ni pendant combien de temps. Si ta politique interne traite tout identifiant sorti de son périmètre comme compromis, c'est le moment de la déclencher plutôt que de le découvrir à l'audit.
Toujours côté identifiants, un correctif nettement plus quotidien : quand apiKeyHelper renvoie des JWT à courte durée de vie, la première requête après une période d'inactivité affichait une erreur d'API visible. Le comportement était structurel, la doc sur la gestion des identifiants précise que le script n'est rappelé qu'au bout de cinq minutes ou sur une réponse 401 : le jeton périmé partait donc une fois avant d'être renouvelé. Désormais un jeton en cache expiré est rafraîchi avant l'envoi, et les erreurs 401 et 403 sont réessayées sans bruit.
Trois fois où une interruption passait pour un succès
Le fil rouge le plus intéressant de cette version, et il n'est jamais énoncé comme tel : trois correctifs distincts portent sur des interruptions rapportées comme des réussites.
Le pire est celui qui ment au modèle et pas à toi. En session headless ou distante, un appel d'outil MCP coupé par un message entrant était rapporté au modèle comme « terminé sans sortie » au lieu d'une erreur d'interruption explicite. La nuance est tout sauf cosmétique : un outil qui ne renvoie rien, pour un modèle, c'est un outil qui n'a rien trouvé. Claude tirait donc des conclusions d'un résultat vide qui n'était pas un résultat. Sur une routine automatisée qui tourne sans personne devant, ça se traduit par un rapport confiant bâti sur du néant.
Le deuxième est celui qui te ment à toi. Une commande interrompue en cours d'exécution s'affichait comme « Ran 1 shell command », sans aucun signe qu'elle avait été coupée.
Le troisième concerne les sous-agents. Un sous-agent qui s'arrête sur sa limite maxTurns renvoie maintenant sa sortie marquée comme partielle, avec l'indication de la poursuivre via SendMessage, au lieu de sembler avoir terminé. C'est le bon correctif, parce que la reprise ne coûtait déjà presque rien : la doc sur les sous-agents indique qu'un sous-agent repris « conserve tout son historique de conversation, y compris les appels d'outils, résultats et raisonnements précédents » et « reprend exactement là où il s'était arrêté ». Tout était en place sauf l'essentiel, savoir qu'il s'était arrêté trop tôt.
Deux autres entrées relèvent de la même logique. Les sessions non interactives (-p, SDK, sessions cloud) poursuivent désormais automatiquement une réponse coupée en plein flux par une erreur serveur, une perte de connexion ou un blocage, au lieu de s'achever sur une erreur. Et les sessions reprises qui échouaient en 400 à chaque tour, quand l'historique sauvegardé contenait des blocs d'outils que l'API Anthropic n'accepte pas (typiquement écrits par un proxy tiers), repartent.
Le balayage qui effaçait tes worktrees
Celui-ci mérite d'être lu deux fois : le balayage de rétention des sessions d'arrière-plan supprimait des worktrees git situés sous .claude/worktrees/ que tu avais créés toi-même, dès qu'un ancien enregistrement de session d'arrière-plan pointait dessus.
Un worktree effacé emporte tout ce qui n'y était pas committé. Si tu utilises ce répertoire pour tes propres worktrees et que tu as vu des dossiers disparaître sans explication, tu as la cause.
Le reste des sessions d'arrière-plan est réparé dans la foulée : elles échouaient à s'ouvrir au bout de 45 secondes quand le répertoire de démarrage de Claude Code avait été supprimé, quand la machine avait dormi, ou sur un hôte lent à lancer des processus. Et elles échouaient avec un « Couldn't start the background service … EACCES » quand un autre processus Claude Code réinstallait le paquet npm au même moment.
/cd devient un vrai changement de projet
Jusqu'ici, /cd déplaçait le répertoire de travail mais tu gardais la configuration du projet précédent jusqu'au redémarrage. C'est corrigé : les réglages projet du nouveau répertoire, ses hooks, ses serveurs .mcp.json (derrière l'habituelle demande d'approbation), ses skills et ses agents prennent effet juste après le déplacement, et non plus au --resume.
Ça fait de /cd un vrai changement de contexte plutôt qu'un cd déguisé. Deux limites que la doc sur les règles Cd précise et que le changelog passe sous silence : Cd n'est pas un outil que le modèle peut appeler, les règles ne s'appliquent que quand tu lances /cd toi-même ; et ajouter une seule règle Cd en autorisation bascule /cd en mode liste blanche, où toute cible non listée est refusée.
Le reste, en vrac
- Transcript beaucoup plus rapide sur les gros diffs : un diff contenant une ligne unique très longue (une chaîne base64, typiquement) provoquait un ralentissement sévère. Ces lignes sont maintenant rendues tronquées, avec un marqueur. Dans la même veine, la mémoire cessait de croître avec la longueur de session dans les vues plein écran et Ctrl+O.
- L'outil Write annonçait « Out of memory » ou se figeait longuement après l'écrasement d'un très gros fichier existant, alors que le fichier avait bien été écrit.
- Arguments MCP mal typés : les arguments d'outil étaient envoyés en chaînes JSON quand le schéma du paramètre est vide (
{}), au lieu de leur type réel. - Permission MCP trompeuse : les outils marqués
requiresUserInteractionproposaient quand même « Oui, et ne me redemande plus », option qui écrivait une règle que l'outil ignorait ensuite. --strict-mcp-configdemandait d'approuver des serveurs.mcp.jsonqu'il n'aurait jamais chargés, ce qui laissait les sessions d'arrière-plan en attente au démarrage.- Workflows dynamiques : appuyer sur ← ou lancer
/backgroundpendant un workflow relançait ses sous-agents déjà terminés. Claude demande maintenant confirmation et annonce combien de sous-agents seraient relancés. /goallimite désormais à trois les relances qu'une session inactive déclenche sur du travail d'arrière-plan long, par objectif. Ton message suivant en réautorise trois.- Une entrée
keybindings.jsonavec un nom d'action inconnu rendait la touche silencieusement morte. Elle est maintenant ignorée, le raccourci par défaut continue de fonctionner, et un avertissement est écrit sous--debug. - Rendu markdown : il était désactivé pour tout un message dès que ses 500 premiers caractères n'en contenaient pas, et il ignorait les listes en
+ouN)et les titres soulignés. - Plein écran : transcript vide après un redimensionnement du terminal, défilement erratique quand tu étais remonté dans l'historique, et vol du focus clavier vers le contrôle sous le pointeur quand tu cliquais juste pour revenir sur la fenêtre.
- Plugins : cache créant des répertoires SHA en double pour un même plugin, préfixe
<plugin>:affiché en double dans le menu des slash commands,claude plugin updateen échec sur un nom court, installation cassée par un BOM UTF-8 dansplugin.json,/reload-pluginsannonçant 0 skill pour les plugins qui les déclarent enskills/*/SKILL.md, et messages d'erreur de hook affichant un${CLAUDE_PLUGIN_ROOT}littéral au lieu du chemin résolu. - Thèmes :
/renameremplaçait la couleur de bordure du prompt par le cyan par défaut, et les couleurs de diff personnalisées étaient ignorées. /code-reviewpeut désormais être lancé par Claude de sa propre initiative sur Bedrock, Vertex AI et Foundry, via le Claude apps gateway, et quand la télémétrie est désactivée.- Détail agréable : la ligne de durée de fin de tour affiche maintenant l'heure d'achèvement, par exemple
✻ Sautéed for 23s · done 6:05 PM.
Ce qu'il faut en retenir
Un seul geste à faire aujourd'hui : lance Claude Code et regarde s'il t'affiche un avertissement sur une règle Bash. S'il le fait, l'étoile est au mauvais endroit et la règle est plus large que ce que tu croyais avoir écrit. C'est cinq minutes de relecture de ton fichier de permissions, et c'est la seule entrée de cette version qui touche à ta surface d'exposition.
Si tu passes par un gateway tiers, ajoute la question de la rotation de ta clé à ta liste. Pour tous les autres, la 2.1.246 n'a rien à apprendre : c'est une version qui répare, dont trois correctifs redonnent au client l'habitude de dire quand quelque chose s'est mal passé. Aucune raison de la retarder.
Pierre Rondeau
Développeur et indie builder. Je construis des produits et automatisations avec l'IA. Créateur de Claude Hub.
LinkedIn