« Missing field ‘review’ (in ‘itemReviewed’) ». L’outil de test des résultats enrichis de Google affiche ce message sur une poignée de fiches produit d’un site e-commerce, sans prévenir, alors que le même gabarit de page fonctionnait sans erreur la semaine précédente. Le réflexe naturel est de soupçonner le plugin SEO ou le thème d’avoir cassé quelque chose lors d’une mise à jour récente — mais dans ce cas précis, ni l’un ni l’autre n’avait été touché.
Ce type d’erreur est trompeur parce qu’il désigne toujours le symptôme final, jamais la cause première. Un champ requis par le type Schema.org concerné (ici Product avec un sous-type Review imbriqué) apparaît vide ou absent dans le JSON-LD généré, mais la raison de cette absence peut se situer à n’importe quel niveau de la chaîne qui va de la donnée brute jusqu’au rendu final.
Symptôme : une validation qui échoue de façon inconstante
Premier élément à noter avant tout diagnostic : l’erreur ne touchait pas 100 % des fiches produit, mais uniquement celles ayant reçu au moins un avis client dans les trente derniers jours — soit une minorité, mais une minorité en croissance, ce qui explique pourquoi le problème n’avait pas été détecté immédiatement. Sur les fiches sans avis, aucun bloc Review n’était généré du tout, donc aucune validation Schema.org de ce sous-type n’était déclenchée. Le bug n’était donc pas une absence totale du champ, mais un champ imbriqué généré de façon incomplète uniquement dans un cas précis.
Diagnostic : remonter le flux plutôt que corriger le symptôme

La méthode a consisté à vérifier successivement quatre niveaux de la chaîne, du plus proche du rendu au plus proche de la donnée source, plutôt que de patcher directement le template de sortie :
1. Le rendu JSON-LD final
{
"@type": "Product",
"review": {
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": "4"
}
}
}
Le champ author, requis par la spécification Schema.org pour le type Review, était absent de cette sortie. C’est le symptôme visible dans l’outil de validation, mais il ne dit encore rien de sa cause.
2. Le code générant ce bloc
function generer_bloc_review( $avis ) {
return array(
'@type' => 'Review',
'reviewRating' => array(
'@type' => 'Rating',
'ratingValue' => $avis['note'],
),
'author' => array(
'@type' => 'Person',
'name' => $avis['auteur'],
),
);
}
Le code, lui, prévoyait bien le champ author. Le problème ne venait donc pas d’un oubli dans le template de génération du balisage, ce qui écartait une première hypothèse évidente.
3. La donnée transmise à cette fonction
En traçant l’appel avec un simple error_log( wp_json_encode( $avis ) ) temporaire, la valeur de $avis['auteur'] apparaissait effectivement vide pour les avis concernés — pas absente de la structure, mais vide, une chaîne de caractères de longueur nulle. Le champ existait donc bien dans le flux de données jusqu’à ce point, sans jamais être rempli correctement.
4. La source d’origine de la donnée
La source racine s’est révélée être un import automatisé des avis clients depuis une plateforme tierce, via une tâche planifiée quotidienne. Le format d’export de cette plateforme avait changé sans annonce préalable : le nom de l’auteur, auparavant transmis dans un champ customer_name, avait été déplacé vers un champ imbriqué customer.display_name, non anticipé par le script d’import, qui continuait de lire l’ancien chemin et récupérait donc systématiquement une valeur vide sans jamais lever d’erreur PHP visible, puisque l’accès à une clé de tableau absente ne provoque qu’un avertissement silencieux en configuration de production standard.
Correctif appliqué
Le correctif a porté sur le script d’import, pas sur la génération du balisage Schema.org elle-même, qui était correcte depuis le début :
$nom_auteur = $donnees_brutes['customer']['display_name']
?? $donnees_brutes['customer_name']
?? 'Client vérifié';
Une valeur de repli explicite (« Client vérifié ») a été ajoutée pour éviter qu’un futur changement de format côté plateforme tierce ne reproduise le même effet de bord silencieux, plutôt que de se contenter de corriger le champ exact identifié aujourd’hui.
Ce que cette investigation a changé dans le processus
- Une validation automatisée de la sortie JSON-LD, exécutée quotidiennement sur un échantillon de pages, a été ajoutée pour détecter ce type de régression avant qu’un volume significatif de pages ne soit affecté.
- Les imports de données tierces influençant un balisage Schema.org sont désormais accompagnés de valeurs de repli explicites pour chaque champ requis par le type concerné.
- Le diagnostic a confirmé qu’un champ optionnel dans la structure de données interne (l’auteur d’un avis, rarement critique en soi) peut devenir un champ strictement obligatoire dès lors qu’il alimente un type Schema.org avec ses propres règles de validation.
Un message de validation Schema.org donne toujours l’adresse du symptôme, jamais celle du coupable : il faut remonter la chaîne de données un niveau à la fois avant de toucher au code de rendu.
Prévention
Pour éviter de reproduire ce type d’incident, il est utile de traiter toute donnée provenant d’une source externe — import, API tierce, flux automatisé — comme potentiellement incomplète, avec une valeur de repli systématique sur chaque champ marqué comme requis par la spécification Schema.org du type concerné, consultable sur schema.org. La validation ponctuelle via l’outil de test de Google reste utile, mais elle ne remplace pas une vérification automatisée récurrente, seule capable de détecter une régression progressive comme celle-ci avant qu’elle n’affecte une part significative du catalogue.