“count(): Argument #1 ($value) must be of type Countable|array” in WordPress: what it means and how to fix it

By CompatNav · Published · Last reviewed · 4 min read

Short answer

It’s a fatal error from PHP 8.0 and later: a plugin or theme asked count() how many items something has, but got nothing (null), a piece of text or a number instead of a list. PHP 7 only showed a warning and carried on; PHP 8 stops the page, so WordPress shows “There has been a critical error on this website”. The file and line in the message lead to the plugin or theme. Update it, or send the message to its developer.

The message, exactly

A theme counts the slides of a slider, and nothing has been saved yet. On PHP 7.4 that gives a warning and the page goes on; on PHP 8.0 the page stops:

wp-content/themes/old-theme/functions.php

<?php
function get_slides() {
    return null; // nothing saved yet
}

$slides = get_slides();
echo 'Slides: ', count($slides), "\n";

Output on PHP 7.4.33

Slides:
Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/html/wp-content/themes/old-theme/functions.php on line 7
0

Output on PHP 8.0.30the script stopped

Slides:
Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in /var/www/html/wp-content/themes/old-theme/functions.php:7
Stack trace:
#0 {main}
  thrown in /var/www/html/wp-content/themes/old-theme/functions.php on line 7

php.net’s changelog for count(): “count() will now throw TypeError on invalid countable types passed to the value parameter.” (PHP 8.0.0), and before that, from 7.2.0: “count() will now yield a warning on invalid countable types passed to the value parameter.” (php.net)

On a WordPress site you see “There has been a critical error on this website.” and WordPress emails the administrator. The full message is in that email, or in your error log.

What “null given” or “string given” tells you

The last words say what count() received instead of a list. A single tag saved as text, for example, used to count as one; on PHP 8 it stops the page too:

wp-content/themes/old-theme/functions.php

<?php
$tags = 'news'; // one tag saved as text instead of a list
echo 'Tags: ', count($tags), "\n";

Output on PHP 7.4.33

Tags:
Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/html/wp-content/themes/old-theme/functions.php on line 3
1

Output on PHP 8.0.30the script stopped

Tags:
Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, string given in /var/www/html/wp-content/themes/old-theme/functions.php:3
Stack trace:
#0 {main}
  thrown in /var/www/html/wp-content/themes/old-theme/functions.php on line 3

null given usually means a value that was never saved; bool given often means false, which many WordPress functions return when they find nothing.

Is it the plugin, the theme, or WordPress?

Read the path in the message: the folder after wp-content/plugins/ or wp-content/themes/ is the culprit, here a theme called old-theme. If the path is in wp-includes/ or wp-admin/, look further down the message (the stack trace) for the first wp-content/ path: WordPress was only passing along a value a plugin gave it.

Fix it, in order

  1. Get the site back if it’s down: switch PHP back in your hosting panel, or use the link in WordPress’s email to log in and pause the plugin. The critical error guide walks through both.
  2. Update the plugin or theme (Dashboard → Updates). Its developer may already have fixed it.
  3. Already on the latest version? Send the full message, including the file and line, to its developer.
  4. No longer maintained? Replace it with a maintained alternative.

Why no check finds it beforehand

The code count($slides) is correct as long as $slides is a list. Whether it is depends on what is saved on your site, so a check that reads code can’t know. CompatNav doesn’t report it; its scan of the examples on this page finds nothing. This is one of the problems that only your error log shows: the WordPress debug log explains how to keep one without showing errors to visitors, and checking it for a few days after a PHP switch catches it early.

Key takeaways

  • Since PHP 8.0, count() on something that isn’t a list stops the page with a TypeError; PHP 7.2 to 7.4 only showed a warning.
  • The end of the message says what it got instead: null given, string given, bool given, …
  • It depends on values: the same code works while a setting holds a list and breaks when it is empty. No code check can see it in advance.
  • Find the plugin from the path in the message, then update it or send the message to its developer.
  • The fix for developers: check with is_countable() (PHP 7.3 and later) before counting.

Frequently asked questions

Why did this start after a PHP update?

The same code ran before, with a warning most sites never displayed. PHP 8.0 turned that warning into an error that stops the page.

Can I go back to the old PHP version?

Yes, as a temporary measure: switching PHP back in your hosting panel brings the site back while the plugin is fixed. Don’t stay there: PHP 7.4 has had no security fixes since 28 November 2022.

Why does it happen on some pages only?

Because it depends on what the plugin finds: a widget with no items saved, an empty search result, a setting that was never filled in. Pages where the list exists keep working.

Will a compatibility check find it?

No check that reads code can, because the code is fine as long as the value is a list. Your error log shows it the first time it happens.

Check your own site before you upgrade

CompatNav is a free WordPress plugin. It reads the code of your plugins and themes on your own server and tells you, in plain words, what will break and what will only show notices on the PHP version you choose. It never changes your code. It can’t see problems that only appear while code runs with real data, so a quick check of your site after the upgrade still matters.

Get CompatNav on wordpress.org How it works

Sources

About the code examples: each output is the real output of the code shown, run with the official PHP builds, without a php.ini, with all errors reported and displayed. Only the file path was replaced by a neutral server path.