Si vous avez déjà cliqué sur Articles dans wp-admin et que tout se fige avec une erreur bizarre du type “v3.1.1 fails to open wp-admin ‘articles’…”, vous avez probablement un conflit entre un plugin (version 3.1.1), un snippet, et la page liste des posts (edit.php).


Le problème

Le message exact varie selon le plugin, le serveur et la langue, mais on retrouve souvent une trace qui commence comme ceci (dans un écran blanc, une page 500, ou un log PHP) :

v3.1.1 fails to open wp-admin "articles" with a fatal error:
Uncaught TypeError: ... in /wp-content/plugins/mon-plugin/...
or
PHP Fatal error:  Uncaught Error: Call to undefined function ...
or
There has been a critical error on this website.

Où ça apparaît :

  • Admin uniquement : en ouvrant Articles > Tous les articles (URL typique : /wp-admin/edit.php), parfois aussi Ajouter (URL : /wp-admin/post-new.php).
  • Parfois en AJAX : l’écran charge, puis une action (filtre, recherche, édition rapide) déclenche une erreur.
  • Plus rarement en REST API : si un plugin modifie la requête des posts via REST, Gutenberg peut aussi être impacté.

Circonstances typiques que j’ai vues en dépannage :

  • Juste après une mise à jour d’un plugin en v3.1.1 (le numéro “3.1.1” est presque toujours celui d’un plugin, pas de WordPress).
  • Après l’ajout d’un snippet “pour renommer Posts en Articles” trouvé dans un ancien tutoriel.
  • Après l’activation d’un plugin SEO / redirection / sécurité qui touche aux capacités (capabilities) ou au menu admin.
  • Sur des sites avec Divi 5, Elementor ou Avada : ces builders ne cassent pas directement edit.php, mais ils cohabitent souvent avec des “snippets” et plugins qui, eux, le cassent.

À qui s’adresse ce guide : si vous débutez, vous saurez identifier quelle brique casse l’écran Articles, récupérer l’accès à l’admin, et appliquer une correction propre sur WordPress 6.9.4 (avril 2026) et PHP 8.1+.

Résumé rapide

  • Le menu Articles pointe vers /wp-admin/edit.php. Si cette page plante, c’est presque toujours un hook admin (action/filtre) d’un plugin ou d’un snippet.
  • Commencez par activer WP_DEBUG_LOG et/ou Health Check pour isoler le plugin fautif sans casser le site public.
  • Cas fréquent : un code de CPT “articles” mal déclaré (register_post_type()) avec des capabilities incohérentes ou un slug qui entre en conflit.
  • Après correction : ré-enregistrez les permaliens et videz les caches (plugin/serveur/navigateur).
  • Si vous ne pouvez plus entrer dans wp-admin : désactivez le plugin via FTP (renommer le dossier) ou WP-CLI.

Les symptômes

Voici ce que vous pouvez observer, du plus fréquent au plus trompeur :

  • Écran blanc en cliquant sur Articles, parfois avec “Erreur critique”.
  • Erreur 500 uniquement sur /wp-admin/edit.php (les autres pages admin marchent).
  • “Désolé, vous n’êtes pas autorisé à accéder à cette page.” alors que vous êtes administrateur.
  • Liste des articles vide (0 résultat), mais des articles existent bien.
  • Filtres / recherche cassés (la page charge, puis planter en triant par auteur/catégorie).
  • Édition rapide (Quick Edit) qui ne s’ouvre plus, ou tourne indéfiniment (souvent un problème AJAX).
  • Console navigateur (F12) : erreurs JS sur edit.php (souvent liées à un script injecté par un plugin).

Signes de conflit plugin/thème :

  • Le problème disparaît si vous désactivez un plugin “récemment mis à jour”.
  • Le problème apparaît seulement pour certains rôles (éditeur, auteur) : suspicion sur les capabilities.
  • Le problème apparaît après un “snippet” collé dans functions.php (thème enfant) ou un plugin de snippets.

Diagnostic rapide : si /wp-admin/edit.php?post_type=page (Pages) fonctionne mais /wp-admin/edit.php (Posts) casse, on est souvent sur un code qui cible spécifiquement post ou le menu “Articles”.

Pourquoi ça arrive

Version débutant : l’écran Articles est une page admin standard. Beaucoup de plugins “améliorent” cette page (colonnes, filtres, tri, restrictions par rôle, stats). Si un plugin (ou un snippet) fait une erreur PHP/JS, c’est cette page qui tombe.

Voici ce qui se passe en coulisses : WordPress charge wp-admin/edit.php, construit une requête de liste (WP_Query), puis exécute une série de hooks. Un hook est un point d’extension. Une action exécute du code à un moment donné, un filtre modifie une valeur (ex : la requête, les colonnes, le HTML). Si un filtre retourne un mauvais type (ex : null au lieu d’un tableau), PHP 8.1+ est moins permissif et peut déclencher une TypeError.

Causes probables (du plus fréquent au plus rare) :

  • Plugin v3.1.1 bogué qui ajoute des colonnes/filtres sur la liste des posts et déclenche une erreur fatale.
  • Snippet ancien (pré-PHP 8 / pré-WordPress moderne) qui utilise un hook inadapté, ou une fonction non chargée.
  • CPT “articles” enregistré avec un slug/capabilities qui entre en conflit avec “post” (Articles natifs) et casse les permissions.
  • Conflit REST/rewrite après migration : permaliens non régénérés, règles de réécriture obsolètes.
  • Cache agressif (cache admin rarissime mais possible via reverse proxy mal configuré) ou minification JS qui casse l’admin.
  • Problème serveur : mémoire PHP trop basse, OPcache corrompu, permissions fichiers, ou PHP < 8.1.

Note “v3.1.1” : WordPress 6.9.4 n’a pas “v3.1.1”. Si vous voyez “v3.1.1”, c’est presque toujours la version d’un plugin (ou d’un thème). Le diagnostic consiste à identifier lequel.

Prérequis avant de commencer

  • Sauvegarde : base de données + fichiers. Ne testez pas “au hasard” sur production.
  • Environnement de test si possible (staging). J’ai souvent vu un simple point-virgule manquant bloquer tout l’admin.
  • Versions : WordPress 6.9.4 et PHP 8.1+ (idéalement 8.2/8.3 si votre hébergeur le permet). Vérifiez dans Outils > Santé du site.
  • Outils :

Activer les logs WordPress (dans wp-config.php, au-dessus de “stop editing”) :

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false ); // Affichez false en prod pour éviter de divulguer des infos

Référence officielle : Debugging in WordPress.

Risque sécurité : n’affichez jamais les erreurs PHP à l’écran en production. Un stack trace peut révéler des chemins, versions, et parfois des secrets.

Solution 1 : corriger un CPT “articles” (slug/capabilities) qui casse l’écran d’admin

Ce cas arrive quand quelqu’un a voulu “créer un type de contenu Articles” alors que WordPress appelle déjà “Articles” les posts natifs (post). Résultat : confusion de labels, menus dupliqués, et parfois un écran “Vous n’êtes pas autorisé…” ou une page qui plante si un plugin s’attend à post mais reçoit un autre post_type.

Concepts :

  • CPT = Custom Post Type (type de contenu personnalisé), déclaré via register_post_type().
  • Slug = identifiant URL (ex : article), utilisé dans les permaliens et parfois dans l’admin.
  • Capabilities = permissions (ex : edit_posts, edit_pages). Si elles sont mal mappées, l’admin refuse l’accès.

Quand suspecter cette cause

  • Vous avez un menu “Articles” qui n’ouvre pas la liste habituelle des posts.
  • Vous voyez une URL du type /wp-admin/edit.php?post_type=articles.
  • Le problème a commencé après l’ajout d’un snippet “register_post_type(‘articles’, …)”.

Où corriger

Le bon endroit : un petit plugin custom (recommandé), ou un mu-plugin (plugin obligatoire) si vous voulez être sûr que ça charge même si le thème change.

  • Ne collez pas ça dans un plugin de snippets si vous êtes en phase de dépannage : si le plugin de snippets casse, vous perdez l’accès.
  • Si vous devez le faire vite : thème enfant functions.php, mais c’est plus fragile.

Code AVANT (cassé)

Exemple réaliste que je retrouve souvent (slug “articles”, capacités incohérentes, et collision de labels) :

<?php
// functions.php (thème enfant) - EXEMPLE CASSÉ
add_action( 'init', function() {
	register_post_type( 'articles', [
		'label' => 'Articles',
		'public' => true,
		'show_in_menu' => true,
		'show_in_rest' => true,
		'rewrite' => [ 'slug' => 'articles' ],
		// Problème : capabilities bricolées, et parfois l’auteur n’a plus accès à edit.php
		'capability_type' => 'page',
		'map_meta_cap' => false,
	] );
} );

Pourquoi ça casse : avec capability_type => 'page' et map_meta_cap => false, vous créez un type qui se comporte comme des pages pour les permissions, mais sans mapping propre. Selon les rôles et les plugins de sécurité, l’accès à la liste peut être refusé ou provoquer des erreurs quand WordPress calcule les caps.

Code APRÈS (corrigé)

Objectif : éviter le conflit avec “Articles” (posts natifs) et avoir des permissions cohérentes. Je conseille :

  • Un slug et un identifiant non ambigus (ex : mag_article ou ressource).
  • Des labels explicites (ex : “Ressources”).
  • Des capabilities mappées correctement via map_meta_cap => true.
<?php
/**
 * Plugin: Mon CPT Ressources (corrigé)
 * Emplacement : /wp-content/mu-plugins/cpt-ressources.php
 * (Créez le dossier mu-plugins s'il n'existe pas)
 */

add_action( 'init', function() {

	$labels = [
		'name'                  => 'Ressources',
		'singular_name'         => 'Ressource',
		'add_new'               => 'Ajouter',
		'add_new_item'          => 'Ajouter une ressource',
		'edit_item'             => 'Modifier la ressource',
		'new_item'              => 'Nouvelle ressource',
		'view_item'             => 'Voir la ressource',
		'search_items'          => 'Rechercher des ressources',
		'not_found'             => 'Aucune ressource trouvée',
		'not_found_in_trash'    => 'Aucune ressource dans la corbeille',
		'all_items'             => 'Toutes les ressources',
		'menu_name'             => 'Ressources',
	];

	register_post_type( 'ressource', [
		'labels'            => $labels,
		'public'            => true,
		'show_in_menu'      => true,
		'show_in_rest'      => true, // Compatible Gutenberg + REST
		'menu_position'     => 21,
		'menu_icon'         => 'dashicons-media-document',
		'supports'          => [ 'title', 'editor', 'thumbnail', 'excerpt', 'author' ],
		'has_archive'       => true,
		'rewrite'           => [ 'slug' => 'ressources', 'with_front' => false ],
		'capability_type'   => 'post',
		'map_meta_cap'      => true, // Important : mapping correct des permissions
	] );

}, 10 );

Pourquoi ça corrige

  • Vous évitez la collision mentale et technique avec “Articles” (posts natifs).
  • WordPress sait calculer les permissions “comme un post” (standard), ce qui réduit énormément les conflits avec plugins de rôles/sécurité.
  • Le CPT est compatible REST/Gutenberg (show_in_rest), ce qui évite des comportements bizarres dans l’éditeur.

Étape indispensable après cette correction

Allez dans Réglages > Permaliens et cliquez Enregistrer (sans rien changer). Ça force WordPress à régénérer les règles de réécriture.

Doc officielle : register_post_type().

Ce scénario est fréquent après :

  • migration de site (URL qui change),
  • activation/désactivation d’un plugin qui crée des CPT/taxonomies,
  • mise à jour “v3.1.1” d’un plugin qui modifie ses slugs,
  • restauration d’une sauvegarde partielle.

Ça ne provoque pas toujours un fatal PHP. Parfois l’écran “Articles” ouvre, mais certains filtres ou actions font des requêtes qui échouent (REST/AJAX), et l’interface semble “cassée”.

Diagnostic rapide (sans code)

  • Testez /wp-admin/edit.php puis /wp-admin/edit.php?post_status=trash.
  • Ouvrez la console navigateur (F12) et regardez l’onglet Réseau : des appels vers /wp-json/ en 404/401/500 ?
  • Allez dans Outils > Santé du site et vérifiez les recommandations (REST API, boucles, etc.).

Correction 1 : flush des permaliens propre (UI)

Le plus sûr : Réglages > Permaliens > Enregistrer.

Correction 2 : flush via WP-CLI (si l’admin est instable)

Si vous avez WP-CLI (souvent sur VPS/managed hosting), exécutez :

wp rewrite flush --hard

Référence WP-CLI : wp rewrite flush.

Code AVANT (cassé) : flush au mauvais endroit

J’ai vu ce snippet provoquer des lenteurs, des timeouts, voire des comportements erratiques en admin :

<?php
// EXEMPLE CASSÉ : flush à chaque chargement
add_action( 'init', function() {
	flush_rewrite_rules(); // Très mauvais : lourd, et peut provoquer des effets de bord
} );

Code APRÈS (corrigé) : flush uniquement à l’activation

Placez ce code dans un plugin custom (ex : /wp-content/plugins/mon-fix/mon-fix.php), puis activez-le. Ensuite vous pouvez le garder (sans flush permanent) ou le supprimer.

<?php
/**
 * Plugin Name: Fix Permaliens (flush à l'activation)
 * Description: Force une régénération des règles de réécriture à l'activation uniquement.
 */

register_activation_hook( __FILE__, function() {
	// On régénère proprement les règles une seule fois
	flush_rewrite_rules();
} );

register_deactivation_hook( __FILE__, function() {
	// Optionnel : on flush à la désactivation si le plugin ajoutait des règles
	flush_rewrite_rules();
} );

Pourquoi ça corrige

  • Vous éliminez un anti-pattern : flush_rewrite_rules() ne doit pas tourner sur chaque page.
  • Vous remettez à plat les règles après un changement de CPT/slug, ce qui stabilise certains écrans admin et les endpoints REST/AJAX liés.

Doc officielle : flush_rewrite_rules().

Solution 3 : traquer une erreur fatale PHP sur l’écran “Articles” (hooks admin, colonnes, filtres)

C’est le cas le plus courant derrière un “v3.1.1 fails to open wp-admin articles…”. Un plugin (v3.1.1) ou un snippet ajoute une colonne, modifie la requête, ou filtre les lignes, et déclenche une erreur PHP (TypeError, undefined function, etc.).

Étape 1 : récupérer l’erreur exacte

Ouvrez wp-content/debug.log après avoir reproduit le bug (cliquer sur Articles). Cherchez une ligne “PHP Fatal error” avec un chemin du type :

PHP Fatal error:  Uncaught TypeError: array_merge(): Argument #2 must be of type array, null given
in /wp-content/plugins/mon-plugin/includes/admin-columns.php:123
Stack trace:
#0 ...

Si vous n’avez pas le log, installez Query Monitor et regardez l’onglet “PHP Errors” (si la page charge partiellement). Doc Query Monitor : WordPress.org.

Étape 2 : isoler sans casser le site public (Health Check)

Avec Health Check & Troubleshooting :

  1. Activez le mode dépannage (uniquement pour votre session).
  2. Testez Articles. Si ça marche : le problème vient d’un plugin/thème désactivé en mode dépannage.
  3. Réactivez les plugins un par un jusqu’à reproduire le crash.

Dans mon expérience, c’est la façon la plus rapide d’identifier “le plugin v3.1.1” sans rendre le site indisponible.

Cas typique : filtre de colonnes qui retourne le mauvais type

Sur edit.php, beaucoup de codes utilisent le filtre manage_posts_columns (ou manage_edit-post_columns) pour ajouter des colonnes. Une erreur classique en PHP 8+ : retourner null au lieu d’un tableau.

Code AVANT (cassé)

Exemple réaliste : un plugin/snippet veut supprimer une colonne, mais oublie de retourner le tableau :

<?php
// EXEMPLE CASSÉ : filtre qui ne retourne rien (donc null)
add_filter( 'manage_posts_columns', function( $columns ) {

	unset( $columns['comments'] );

	// Oubli : return $columns;
}, 10, 1 );

Résultat possible : plus loin, WordPress (ou un autre plugin) fait un array_merge() sur $columns et obtient null → TypeError → écran Articles HS.

Code APRÈS (corrigé)

Collez ce correctif dans un plugin custom (ou functions.php du thème enfant) après sauvegarde. Si vous suspectez un plugin, corrigez plutôt dans votre propre code et désactivez le plugin fautif.

<?php
/**
 * Correctif : toujours retourner un tableau de colonnes.
 * Emplacement : functions.php (thème enfant) OU plugin custom.
 */
add_filter( 'manage_posts_columns', function( $columns ) {

	if ( ! is_array( $columns ) ) {
		// Sécurité : évite les TypeError si un autre code a renvoyé n'importe quoi
		$columns = [];
	}

	unset( $columns['comments'] );

	return $columns;

}, 10, 1 );

Pourquoi ça corrige

  • Un filtre doit retourner une valeur. Sinon WordPress récupère null.
  • Le garde-fou is_array() vous protège même si un autre plugin renvoie un type incorrect.

Doc officielle sur les hooks (actions/filtres) : Plugin API: Hooks.

Cas typique : hook “pré-requête” qui casse la liste (pre_get_posts)

Un autre classique : on veut filtrer les posts en admin, et on modifie toutes les requêtes, y compris celles de l’admin liste. La page “Articles” devient vide, lente, ou plante si la requête devient invalide.

Code AVANT (cassé)

<?php
// EXEMPLE CASSÉ : modifie toutes les requêtes, y compris l'admin
add_action( 'pre_get_posts', function( $query ) {

	// Mauvais : pas de garde-fous, touche REST, admin, widgets, etc.
	$query->set( 'posts_per_page', 500 );
	$query->set( 'post_status', 'publish' );

} );

Code APRÈS (corrigé)

Objectif : ne toucher qu’à la requête principale du front, pas l’admin. Placez-le dans un plugin custom ou le thème enfant.

<?php
/**
 * Correctif : limiter l'impact de pre_get_posts.
 * Emplacement : functions.php (thème enfant) OU plugin custom.
 */
add_action( 'pre_get_posts', function( $query ) {

	// Toujours vérifier qu'on ne casse pas l'admin
	if ( is_admin() ) {
		return;
	}

	// Ne modifier que la requête principale
	if ( ! $query->is_main_query() ) {
		return;
	}

	$query->set( 'posts_per_page', 12 );

}, 10, 1 );

Doc officielle : pre_get_posts.

Cas typique : script JS injecté en admin qui casse edit.php

Si la console affiche des erreurs JS, cherchez un plugin qui enfile (enqueue) un script partout dans l’admin, parfois minifié, parfois dépendant d’une librairie absente.

Code AVANT (cassé)

<?php
// EXEMPLE CASSÉ : charge un script admin partout, sans dépendances ni ciblage
add_action( 'admin_enqueue_scripts', function() {
	wp_enqueue_script(
		'mon-admin',
		plugin_dir_url( __FILE__ ) . 'admin.js',
		[],
		'3.1.1',
		true
	);
} );

Code APRÈS (corrigé)

On cible uniquement l’écran “Articles” (posts) et on déclare des dépendances raisonnables.

<?php
/**
 * Correctif : charger le JS uniquement sur l'écran des articles.
 * Emplacement : plugin custom (recommandé).
 */
add_action( 'admin_enqueue_scripts', function( $hook_suffix ) {

	// L'écran liste des posts natifs est généralement edit.php
	if ( 'edit.php' !== $hook_suffix ) {
		return;
	}

	// Optionnel : s'assurer qu'on est bien sur post (et pas un CPT)
	$post_type = isset( $_GET['post_type'] ) ? sanitize_key( $_GET['post_type'] ) : 'post';
	if ( 'post' !== $post_type ) {
		return;
	}

	wp_enqueue_script(
		'mon-admin',
		plugin_dir_url( __FILE__ ) . 'admin.js',
		[ 'jquery' ], // Exemple : dépendance explicite si votre script utilise jQuery
		'3.1.2', // Bump de version pour casser le cache navigateur
		true
	);

}, 10, 1 );

Doc officielle : admin_enqueue_scripts et wp_enqueue_script().

Vérifications après correction

  • Rechargez /wp-admin/edit.php en navigation privée (évite un cache agressif).
  • Testez :
    • Recherche d’un article
    • Filtre par catégorie
    • Édition rapide
    • Corbeille
  • Vérifiez wp-content/debug.log : plus de “Fatal error” au moment du clic.
  • Si vous avez un plugin de cache : videz cache plugin + cache serveur (si applicable) + cache navigateur.

Si le bug était un conflit de permissions/capabilities : testez avec un compte “Éditeur” (pas seulement admin). Beaucoup de sites “semblent” réparés en admin mais restent cassés pour les rôles inférieurs.

Si ça ne marche toujours pas

Procédure de dépannage que j’applique quand l’écran “Articles” reste inaccessible.

1) Désactiver le plugin fautif sans wp-admin (FTP)

  1. Connectez-vous en FTP/SFTP.
  2. Allez dans /wp-content/plugins/.
  3. Renommez le dossier du plugin suspect (ex : mon-pluginmon-plugin.off).
  4. Rafraîchissez wp-admin.

Si vous ne savez pas lequel : renommez temporairement plugins en plugins.off (désactive tous les plugins), puis remettez et réactivez un par un.

2) Vérifier la mémoire PHP

Une liste d’articles lourde (beaucoup de colonnes, requêtes, stats) peut exploser la mémoire. Regardez l’erreur “Allowed memory size…”.

Vous pouvez augmenter la limite WordPress (si l’hébergeur le permet) :

<?php
// wp-config.php
define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' ); // Pour l'admin

Référence : wp-config.php (constants).

3) Vérifier la version PHP

Si vous êtes en PHP 7.4/8.0, certains plugins récents (ou WordPress 6.9.4) peuvent se comporter différemment. Visez PHP 8.1 minimum.

Doc : PHP Supported Versions.

4) Vérifier les erreurs REST/AJAX

  • Ouvrez /wp-json/ : doit répondre en JSON (pas une 404 HTML).
  • Regardez si un plugin de sécurité bloque /wp-json/ ou admin-ajax.php.

Doc REST : WordPress REST API Handbook.

5) Query Monitor : repérer le hook/filtre qui casse

Si la page charge partiellement, Query Monitor peut vous montrer :

  • erreurs PHP
  • requêtes lentes
  • scripts/styles en erreur
  • hooks déclenchés

6) Dernier recours : activer le mode récupération

WordPress a un mécanisme de “recovery mode” quand un plugin déclenche une erreur fatale en admin. Si vous recevez un e-mail “Votre site rencontre une erreur technique”, utilisez le lien de récupération pour désactiver le plugin fautif.

Doc : Recovery Mode (support).

Pièges et erreurs courantes

Tableau de diagnostic

Symptôme Cause probable Vérification Solution
Erreur critique uniquement sur “Articles” Plugin v3.1.1 ajoute colonnes/filtres et plante debug.log montre un chemin dans /plugins/… Désactiver/rollback le plugin, corriger le hook (Solution 3)
“Désolé, vous n’êtes pas autorisé…” Capabilities CPT mal mappées ou plugin de rôles Test avec admin vs éditeur, inspecter CPT Corriger CPT/caps (Solution 1), revoir plugin de rôles
Liste vide (0 articles) mais ils existent pre_get_posts modifie la requête admin Désactiver snippet, vérifier code pre_get_posts Ajouter garde-fous is_admin/is_main_query (Solution 3)
Édition rapide ne s’ouvre pas Erreur JS admin ou admin-ajax bloqué Console F12 + onglet Réseau Cibler l’enqueue, désactiver minification, autoriser AJAX
Problème après migration Rewrite rules obsolètes Réglages > Permaliens, test /wp-json/ Flush permaliens (Solution 2)

Erreurs que je vois tout le temps

  • Copier le code au mauvais endroit : coller un snippet PHP dans un champ “CSS” du builder, ou dans l’éditeur de page. Résultat : rien ne marche, ou le code s’affiche en clair.
  • Oublier un point-virgule dans functions.php : une simple faute bloque tout wp-admin. Travaillez sur un staging et gardez un accès FTP.
  • Utiliser un hook inadapté : par exemple modifier la requête admin via pre_get_posts sans is_admin().
  • Confusion actions vs filtres : un filtre doit retourner quelque chose. Une action, non. Ici, une erreur de retour peut casser “Articles”.
  • Cache non vidé : vous corrigez, mais le navigateur sert l’ancien JS (version). Incrémentez la version du script et videz le cache.
  • Tester en production sans sauvegarde : sur l’admin, ça peut vous verrouiller dehors.
  • Snippet cassé par un plugin de snippets : si le plugin de snippets plante, vous ne pouvez plus le désactiver facilement. Préférez un mu-plugin pour les correctifs.
  • Code d’ancien tutoriel incompatible PHP 8.1+ (TypeError, paramètres obligatoires, etc.).

Variante / alternative

Méthode sans code : rollback de la version “v3.1.1”

Si vous avez identifié que “v3.1.1” est la version d’un plugin et que le bug est apparu immédiatement après :

  • Regardez dans la page du plugin sur WordPress.org s’il y a une section Advanced View permettant de télécharger une version précédente.
  • Ou utilisez un plugin de rollback (ex : WP Rollback) avec prudence et uniquement depuis une source fiable.

Ensuite, ouvrez un ticket au support du plugin avec :

  • votre version WordPress (6.9.4), PHP,
  • l’erreur complète du log,
  • les étapes pour reproduire.

Méthode avancée : mu-plugin “pare-chocs” pour éviter les fatals sur edit.php

Quand vous devez stabiliser un admin en urgence, vous pouvez neutraliser un hook connu (par exemple un filtre de colonnes) en le remplaçant par un code défensif. Attention : c’est du contournement. Il faut ensuite corriger à la source.

Exemple : vous avez identifié un filtre qui renvoie parfois null. Vous ne pouvez pas modifier le plugin (ou vous ne voulez pas toucher à son code). Vous ajoutez un filtre tardif qui “répare” :

<?php
/**
 * Emplacement : /wp-content/mu-plugins/admin-edit-php-safety.php
 * Objectif : sécuriser le tableau des colonnes si un plugin renvoie un type invalide.
 */

add_filter( 'manage_posts_columns', function( $columns ) {

	// Si un plugin a renvoyé null, on rétablit un tableau minimal
	if ( ! is_array( $columns ) ) {
		$columns = [
			'cb'    => '<input type="checkbox" />',
			'title' => 'Titre',
			'date'  => 'Date',
		];
	}

	return $columns;

}, 9999, 1 );

Ça ne “répare” pas le plugin, mais ça peut vous redonner l’accès à l’écran pour poursuivre le diagnostic.

Éviter ce problème à l’avenir

  • Évitez d’appeler un CPT “articles” : gardez “Articles” pour les posts natifs. Nommez vos CPT selon leur rôle métier (ressources, projets, recettes…).
  • Pas de flush permanent : flush_rewrite_rules() uniquement à l’activation/désactivation.
  • Code défensif sur les filtres : validez les types (is_array, is_string) quand vous filtrez des valeurs utilisées par d’autres plugins.
  • Staging systématique avant mise à jour de plugins majeurs. Une v3.1.1 peut contenir une régression sur un écran admin spécifique.
  • Surveillez les erreurs : gardez WP_DEBUG_LOG activable facilement et mettez en place une rotation des logs côté serveur.
  • Plugins et builders : Divi 5 / Elementor / Avada n’empêchent pas ces corrections. Par contre, évitez les plugins “tout-en-un” de performance qui minifient aussi l’admin : c’est une source classique d’erreurs JS sur edit.php.

Si vous développez : documentez vos hooks. Un filtre qui ne retourne rien est une bombe à retardement, surtout avec PHP 8.1+.

Ressources

Questions fréquentes

Comment savoir quel plugin correspond à “v3.1.1” ?

Regardez wp-content/debug.log : le chemin du fichier fautif pointe presque toujours vers /wp-content/plugins/nom-du-plugin/. Sinon, passez par Health Check en réactivant les plugins un par un.

Je n’ai pas accès à wp-admin, je fais comment ?

Renommez le dossier du plugin suspect via FTP/SFTP (ou désactivez tous les plugins en renommant /wp-content/plugins). Ensuite reconnectez-vous et réactivez progressivement.

Divi 5 / Elementor / Avada peuvent-ils provoquer ce bug ?

Ils le provoquent rarement directement sur edit.php. Mais un add-on, un plugin de snippets, ou une optimisation (minification) installée “avec le builder” peut casser l’admin. Le diagnostic reste le même : logs + isolation plugin.

Pourquoi l’erreur n’apparaît que sur “Articles” et pas ailleurs ?

Parce que beaucoup de plugins accrochent des hooks spécifiques à la liste des posts (colonnes, tri, filtres, restrictions). Une erreur dans ce code ne se déclenche que sur wp-admin/edit.php.

Est-ce que je peux corriger en modifiant le plugin fautif ?

Évitez. Toute mise à jour écrasera vos modifications. Préférez : (1) un correctif dans un plugin custom/mu-plugin, (2) signaler le bug au développeur, (3) changer de plugin si le support est absent.

J’ai corrigé le code mais rien ne change.

Videz les caches (plugin, serveur, navigateur). Si c’est du JS admin, incrémentez la version dans wp_enqueue_script(). Vérifiez aussi que vous avez modifié le bon fichier (thème enfant vs thème parent).

“Désolé, vous n’êtes pas autorisé…” alors que je suis admin.

Ça arrive si un plugin de rôles/sécurité a modifié les capabilities, ou si un CPT a des capabilities incohérentes. Désactivez temporairement le plugin de rôles, puis corrigez la déclaration du CPT (Solution 1).

La liste des articles est vide, mais le front affiche encore des posts.

Un hook pre_get_posts ou un plugin de restriction peut modifier la requête uniquement en admin. Cherchez un snippet qui force post_status, author, ou posts_per_page sans garde-fous is_admin().

Quelle est la meilleure façon de coller un correctif durable ?

Un mu-plugin si vous voulez que le correctif soit toujours actif, même si le thème change. Sinon un plugin custom classique. Évitez de dépendre d’un thème pour de la logique admin.

À quel moment dois-je contacter mon hébergeur ?

Si vous voyez des erreurs 500 sans trace dans debug.log, ou des problèmes de permissions/OPcache, ou si PHP est trop ancien et vous ne pouvez pas le changer. Donnez-lui l’heure exacte du test et l’URL /wp-admin/edit.php pour corréler avec les logs serveur.