Le WordPress d'aujourd'hui, décodé pour les développeurs

IA & MCP

« Undefined array key » face à une réponse JSON incomplète d’une API de LLM

Diagnostiquer et corriger un avertissement PHP provoqué par une réponse d'API de modèle de langage mal formée ou tronquée.

Par WordPress Développement • 26 mai 2023 • 4 min de lecture • Aucun commentaire
« Undefined array key » face à une réponse JSON incomplète d'une API de LLM

Warning: Undefined array key "content" in /wp-content/plugins/mon-plugin/inc/api.php on line 47. Cet avertissement, capturé dans les journaux d’erreurs un jeudi soir, ne se produisait que sur environ un appel sur cinquante, ce qui rendait sa reproduction en local particulièrement difficile.

Le code fautif suivait pourtant une structure a priori robuste : un appel à l’API, un décodage JSON, puis un accès direct à la clé attendue dans la réponse. Le problème ne venait ni du réseau ni du décodage, mais de la forme même du contenu renvoyé par l’API dans certains cas précis.

Symptôme

Le code en cause ressemblait à ceci, avec un accès direct sans vérification préalable :

$donnees = json_decode( wp_remote_retrieve_body( $reponse ), true );
$texte   = $donnees['choices'][0]['message']['content'];

La très grande majorité des appels fonctionnaient sans problème. L’avertissement n’apparaissait que sur certaines requêtes, sans lien apparent avec le contenu du prompt envoyé.

Diagnostic

Un ajout temporaire de journalisation, enregistrant la réponse brute complète dans un fichier dès qu’un accès échouait, a permis d’isoler la cause : sur les prompts les plus longs, l’API interrompait parfois la génération avant la fin, faute d’espace suffisant dans la limite de jetons de sortie configurée. La réponse renvoyée contenait alors un champ finish_reason à length, et la structure du message ne suivait pas exactement le format habituel dans ce cas de troncature.

{
  "choices": [
    {
      "finish_reason": "length",
      "message": { "role": "assistant" }
    }
  ]
}

Le champ content était absent du message dans cette situation précise, alors que le code supposait sa présence systématique. Le code HTTP renvoyé restait 200 : rien, du point de vue du protocole, ne signalait un problème.

Correctif

L'essentiel à retenir : L'avertissement apparaît par intermittence, jamais à chaque appel ; La réponse peut être tronquée sans code d'erreur HTTP ; Une validation de structure évite l'avertissement à la source

La correction combine deux mesures : une validation explicite de la structure avant tout accès, et une vérification du champ finish_reason pour distinguer une réponse tronquée d’une réponse complète.

$donnees = json_decode( wp_remote_retrieve_body( $reponse ), true );

$raison = $donnees['choices'][0]['finish_reason'] ?? null;
$texte  = $donnees['choices'][0]['message']['content'] ?? null;

if ( 'length' === $raison ) {
    error_log( 'Réponse tronquée par manque de jetons disponibles' );
    return null;
}

if ( null === $texte ) {
    error_log( 'Structure de réponse inattendue : ' . wp_json_encode( $donnees ) );
    return null;
}

return $texte;

L’opérateur de coalescence nulle ?? évite l’avertissement en remplaçant l’accès direct par une valeur par défaut explicite, tout en gardant la trace de l’anomalie dans les journaux pour investigation ultérieure.

Prévention

La cause profonde restait la limite de jetons de sortie fixée trop bas par rapport à la longueur habituelle des prompts envoyés. Deux ajustements complémentaires ont suivi le correctif immédiat :

  • Augmentation de la limite de jetons de sortie configurée dans l’appel
  • Ajout d’un contrôle de longueur du prompt avant envoi, avec un avertissement si la marge devient trop faible
  • Écriture d’une fonction utilitaire unique de décodage, réutilisée partout où une réponse d’API est traitée

Généraliser la validation

Cette fonction utilitaire, centralisée, évite qu’un accès direct sans vérification ne se réintroduise ailleurs dans le code au fil des évolutions du plugin :

function extraire_texte_reponse( array $donnees ): ?string {
    return $donnees['choices'][0]['message']['content'] ?? null;
}

Un code HTTP 200 ne garantit jamais qu’une réponse d’API contient tout ce que l’on attend d’elle : la structure du corps de la réponse mérite sa propre vérification, indépendante du code de statut.

Pour aller plus loin

Cet incident illustre un principe plus général : une réponse d’API externe, même documentée, doit être traitée comme potentiellement incomplète. La validation explicite de chaque champ attendu, plutôt que la confiance dans la structure documentée, évite ce type d’avertissement intermittent, particulièrement difficile à reproduire en environnement de test.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi