Les mods qui échouent à la validation
Référence : scan du catalogue communautaire du 2026-10-04, Claude Code 2.1.289
Le catalogue awesome-claude-code-mods exécute claude plugin validate sur chaque mod trouvé et enregistre le résultat. Cet article a lu ces 1 919 résultats en entier. Il montre pourquoi des entrées n’ont pas pu entrer dans le répertoire, ce qui est utile si vous créez des mods.
Les résultats en un coup d’œil
Section intitulée « Les résultats en un coup d’œil »| Type | Réussite | Avertissement | Échec | Inconnu |
|---|---|---|---|---|
mod |
1 485 | 224 | 31 | 12 |
fixture (exemple de test) |
62 | 16 | 12 | 3 |
catalog |
38 | 1 | 0 | 0 |
duplicate |
15 | 11 | 2 | 0 |
builtin |
3 | 0 | 1 | 0 |
mirror |
2 | 0 | 1 | 0 |
| Total | 1 605 | 252 | 47 | 15 |
Les 15 cas « inconnu » ne sont pas des échecs de validation. Pour 11 d’entre eux, le dépôt n’a pas pu être lu et le catalogue montre le résultat précédent ; pour les 4 autres, l’entrée n’a pas été retrouvée lors de ce scan.
Le répertoire des mods de ce site ne retenait d’abord que les « réussites » ; depuis le 6 octobre, il affiche aussi les 224 mods ordinaires passés avec avertissements, marqués « avertissement ». Les 31 échecs en restent exclus. Comme on le voit plus bas, les avertissements sont pour la plupart faciles à corriger.
Les 47 échecs, par cause
Section intitulée « Les 47 échecs, par cause »Nous les avons classés selon la première cause du message d’erreur.
| Cause | Cas | Dont mods ordinaires | Exemple |
|---|---|---|---|
Nom réservé (commence par claude-) |
19 | 15 | claude-council, claude-stats |
Fichier de module visé par hooks.json absent |
6 | 5 | self-improvement-loop |
| Fichier importé absent ou hors du dossier | 5 | 3 | jev-context, persona-panel |
| Clé absente du contrat d’état | 3 | 3 | wavy-usage, terminal-gym |
Flux de télémétrie anthropic |
3 | 0 | Le telemetry intégré et ses copies |
| Erreur de syntaxe | 3 | 1 | agents-skills |
Valeur de retour de on() stockée dans une variable |
2 | 2 | shunt |
| Nom d’événement inexistant | 2 | 0 | Exemples de test |
Variable passée à $.env.get |
1 | 1 | Une copie de fast-jev-compaction |
| Manifeste absent | 1 | 1 | pilot-guard |
Deux entrées dans modules |
1 | 0 | Exemple de test |
Champ userConfig manquant |
1 | 0 | Exemple de test |
Parmi les 12 exemples de test, beaucoup sont faux exprès. Si l’on ne regarde que les 31 mods ordinaires, les noms réservés comptent pour 15 cas, soit près de la moitié.
Noms réservés
Section intitulée « Noms réservés »19 cas ont reçu la même erreur. Voici le texte du validateur, tel quel.
Plugin name "claude-council" is reserved: it passes as one of Anthropic's own.A third party's plugin name cannot start with "claude-", "anthropic-", "anthropics-",or "cc-plugin-", be "claude", "anthropic", "anthropics", "claude-code", or"claude-mods", or put "official" beside "claude" or "anthropic". Name it for whatit does.claude-cat, claude-queue, claude-mermaid, claude-games, claude-link, claude-who et claude-slots ont échoué pour la même raison. Sur ces 19 cas, 17 n’ont reçu que cette seule erreur. Quand claude se trouve au milieu du nom, il n’y a pas d’échec, mais parfois un avertissement : relancé avec la 2.1.291, mindful-claude a reçu l’avertissement « reads as one of Anthropic’s own ».
Fichiers absents
Section intitulée « Fichiers absents »6 cas ont échoué parce que le fichier visé par modules dans hooks/hooks.json n’existe pas dans le dépôt. Deux d’entre eux visaient un résultat de build sous dist/ (dist/hook-module.js, dist/integrations/claude.js). Si vous ne commitez pas le résultat du build, le fichier manque aussi chez la personne qui installe. Le module peut pointer directement vers le fichier source .ts ou .tsx : le moteur le lit lui-même.
Sur les 5 échecs d’import, 2 concernaient un fichier existant mais situé hors du dossier du mod.
cannot import "../../../character-core/src/index.ts" (from hooks/function/register.js):it is outside the plugin's folder (packages/persona-panel)C’est ce qui arrive quand un monorepo importe un paquet commun par chemin relatif. Le validateur interdit d’importer des fichiers hors du dossier du mod. Copiez le code commun dans le dossier du mod.
Clés absentes du contrat d’état
Section intitulée « Clés absentes du contrat d’état »Un mod qui déclare un fichier de contrat d’état via "types" dans plugin.json doit inscrire dans le PluginState de ce fichier toutes les clés qu’il utilise avec $.state. terminal-gym a oublié 8 clés et a reçu 8 lignes d’erreur.
terminal-gym.history is not declared: the manifest's types contract must name itin interface PluginState { terminal-gym: { history: ... } }Les mods intégrés échouent aussi
Section intitulée « Les mods intégrés échouent aussi »Le mod intégré telemetry du dépôt anthropics/claude-code apparaît lui aussi en échec.
its hooks stand on the telemetry stream "anthropic" (a matcher names it, or atelemetry hook names no "to" and so stands on every stream), which is for theplugins built into the CLI; name the collector on each telemetry hook:on("telemetry.log", { to: "collector" }, hook)Validé depuis un dossier, il est traité par le validateur comme un mod extérieur. Le flux anthropic est réservé aux plugins intégrés au CLI, et le validateur le refuse. Si votre mod accroche un hook de télémétrie, écrivez toujours { to: "collector" }. Sans to, le hook est considéré comme accroché à tous les flux.
Règles de forme du code
Section intitulée « Règles de forme du code »Le validateur lit le code source selon une forme déterminée. Tout écart fait échouer le mod avant même son exécution.
| Règle | Code en échec | Forme corrigée |
|---|---|---|
La valeur de retour de on() n’accepte que .catch, sur place |
const registration = on("command.run", ...) |
on(...).catch(handler) |
$.env.get n’accepte qu’une chaîne littérale |
$.env.get(name) |
$.env.get("TYPESAFE_API_KEY") |
| Le nom de l’événement doit être exact | on("classic.SessionStartt", ...) |
on("classic.SessionStart", ...) |
Un hook turn.step doit être un générateur asynchrone |
async ($, e, next) => ... |
async function* ($, e, next) { ... } |
modules ne contient qu’un seul module |
Une deuxième entrée | Un seul module d’entrée qui fait les import du reste |
La règle de turn.step est la seconde erreur reçue par claude-slots, en plus de l’erreur de nom. agents-skills a échoué parce que le parseur n’a pas su lire un littéral d’expression régulière à la ligne 89 de hooks/discover/scan.ts.
Les 252 avertissements
Section intitulée « Les 252 avertissements »252 entrées se sont terminées sur un avertissement, dont 224 mods ordinaires. Le catalogue ne conserve pas le texte des avertissements. Nous avons donc cloné superficiellement les 43 mods en état d’avertissement (12 dépôts) et relu leur sortie avec claude plugin validate de Claude Code 2.1.291. Le validateur ne lit que le code source et n’exécute pas le mod. Les 43 ont de nouveau obtenu « passed with warnings ». Un même mod peut recevoir plusieurs avertissements.
| Avertissement | Sur 43 mods |
|---|---|
author: No author information provided. Consider adding author details for plugin attribution |
40 |
root: CLAUDE.md at the plugin root is not loaded as project context. |
2 |
| Nom qui se lit comme celui d’Anthropic | 1 |
${CLAUDE_PLUGIN_ROOT} sans guillemets dans un hook de commande |
1 (14 lignes) |
| Lien symbolique lu sans être suivi | 1 |
Sur l’ensemble du catalogue, le tableau est le même : sur 252 avertissements, 169 viennent d’un champ auteur vide, contre un seul cas parmi les 1 605 entrées réussies. Autrement dit, de nombreux mods reçoivent un avertissement faute d’une ligne author dans plugin.json.
Vous verrez aussi souvent la ligne gating hook without .catch: dans la sortie de validation. Ce n’est pas un avertissement. Elle indique seulement qu’un hook accroché à un endroit où l’on peut refuser (comme tool.call ou prompt.submit) n’a pas de .catch. En cas d’erreur, un tel hook est ignoré et la requête passe telle quelle. Si le hook est fait pour bloquer, ajoutez un .catch.
Les 184 alertes de caractères de contrôle
Section intitulée « Les 184 alertes de caractères de contrôle »Le catalogue effectue, en plus du validateur, une vérification qui lui est propre : l’avertissement ui-control-characters. Elle compte 184 cas au total, dont 152 sur des mods présents dans le répertoire.
UI hook source contains control-character strings. Review any values passed tonext() as rewritten props.text; the scanner does not trace whether these stringsreach that call.La lecture du code source du scanner du catalogue (tools/compatibility.mjs) montre une règle simple. Dans le module de hook d’un mod qui accroche ui.render et dans les fichiers qu’il importe par chemin relatif, le scanner signale tout littéral de chaîne contenant un caractère U+0000–0008, U+000B–001F ou U+007F–009F. La tabulation et le saut de ligne sont exclus. Il ne cherche pas à savoir si cette chaîne arrive à l’écran.
Du code sans rapport avec l’affichage est donc signalé lui aussi. Voici des cas que nous avons ouverts nous-mêmes.
| Mod | Chaîne signalée | Usage |
|---|---|---|
| diff-viewer | '\u0000' |
Détection de fichier binaire |
| gb-pane | '\u0001F ' |
Séparateur de messages internes |
| data-peek | '\r' |
Traitement des fins de ligne CSV |
| diff intégré | Plusieurs lignes sous git/parse/ |
Analyse de la sortie de git |
Cette alerte devient un vrai problème quand vous passez au moteur une chaîne comme un code couleur ANSI (\x1b[31m). Selon le fichier de types, Code n’accepte comme caractères de contrôle que la tabulation et le saut de ligne dans source, Markdown de même dans text, et le moteur refuse les caractères de contrôle dans le title d’un panneau. Donnez les couleurs avec des propriétés de Text comme color et bold. Si vous devez afficher telle quelle une sortie de terminal, supprimez les caractères de contrôle avant de la transmettre.
Liste de contrôle pour les auteurs
Section intitulée « Liste de contrôle pour les auteurs »| Vérification | Échec évité |
|---|---|
Le nom ne commence pas par claude-, anthropic- ou cc-plugin-, et dit ce que fait le mod |
Nom réservé |
plugin.json contient author |
Avertissement |
modules dans hooks.json pointe vers un seul fichier source commité |
Fichier de module absent |
| Tous les fichiers importés sont dans le dossier du mod | Import hors du dossier |
Toutes les clés $.state figurent dans PluginState du fichier de contrat |
Contrat d’état |
Écrire $.env.get("NOM") avec un littéral |
Variable passée |
Enchaîner .catch directement après on(...) |
Valeur de retour conservée |
Le hook turn.step est une async function* |
Règle du générateur |
Le hook de télémétrie contient { to: "collector" } |
Flux anthropic |
${CLAUDE_PLUGIN_ROOT} d’un hook de commande est entre guillemets |
Avertissement |
| Les codes ANSI sont retirés des textes transmis à l’affichage | Caractères de contrôle |
Avant de publier, exécutez ces deux commandes.
claude plugin validate ./my-modclaude plugin test ./my-modvalidate lit en une fois le manifeste, le fichier de marketplace et les modules de hooks, et signale tout ce qu’il refuse. Quand les avertissements tombent eux aussi à 0, le mod figure dans le catalogue et dans le répertoire de ce site sans la mention d’avertissement. La procédure de publication se trouve dans Publier votre mod, et ce qu’il faut consulter quand un mod ne se charge pas dans Dépannage.
Guide communautaire non officiel, sans lien avec Anthropic ni approuvé par Anthropic. Claude et Claude Code sont des marques d’Anthropic.