“foreach() argument must be of type array|object, null given”: what it means and the fix

By CompatNav · Published · Last reviewed · 3 min read

Short answer

It’s a warning: a plugin or theme loops over a list with foreach, but at that moment the variable is not a list: null (nothing found), false, a text or a number. PHP skips the loop and the page keeps going, just without what the loop would have shown. PHP 8 introduced this wording; PHP 7.4 said “Invalid argument supplied for foreach()” for the same thing. The end of the message names what PHP got: null given, string given, bool given. Update the plugin or theme; the developer fix is a check before the loop.

The message, on PHP 7.4 and PHP 8

A related-posts plugin loops over the posts it found. For this post it found none, so the variable is null:

wp-content/plugins/related-posts-lite/related.php

<?php
$related = null; // no related posts found for this post
foreach ($related as $post_id) {
    echo "Related post: $post_id\n";
}
echo "The page goes on\n";

Output on PHP 7.4.33

Warning: Invalid argument supplied for foreach() in /var/www/html/wp-content/plugins/related-posts-lite/related.php on line 3
The page goes on

Output on PHP 8.0.30

Warning: foreach() argument must be of type array|object, null given in /var/www/html/wp-content/plugins/related-posts-lite/related.php on line 3
The page goes on

Both versions skip the loop and print the rest of the page. Only the wording changed: PHP 8 names what it got instead of a list.

What it means

foreach goes through a list (an array) or an object, item by item. php.net: “foreach will issue an error when used with a variable containing a different data type or with an uninitialized variable.” (php.net)

So the plugin expected a list and got something else. The last words of the message tell you what:

The message ends withThe variable was
null givenempty: nothing found, or never set
bool given (PHP 8.0–8.2), false given (8.3 and later)false, which many WordPress functions return when there’s nothing
true given (8.3 and later)true, for example a yes/no setting where a list was expected
string givena text, for example a setting saved in an old format
int givena number, such as an ID where a list of IDs was expected

Who fixes it

  1. Find the plugin or theme: the folder after wp-content/plugins/ or wp-content/themes/ in the message.
  2. Note when it happens: which page, which product or post. It helps the developer reproduce it.
  3. Update it (Dashboard → Updates), and if it still appears, send the message and the page to its developer.
  4. Keep it off your pages meanwhile: log PHP messages instead of showing them, as in the WordPress debug log.

Can a check find it before the upgrade?

Not by reading code: the loop is correct whenever the variable holds a list. We ran CompatNav’s scanner on the example above, and it reports nothing, rightly. But there’s an easy check you can do on PHP 7.4: search your error log for “Invalid argument supplied for foreach()”. Every line you find is a place that will show this message on PHP 8. Finding PHP notices on real visits covers collecting them on a live site.

Similar warnings that depend on values: “Trying to access array offset on value of type null” and “count(): Argument #1 must be of type Countable|array”, which is a fatal error, not a warning.

Key takeaways

  • A warning, not a fatal error: the loop is skipped and the page goes on.
  • On PHP 7.4 the same problem read “Invalid argument supplied for foreach()”.
  • “null given”, “false given”, “string given”: what the variable held instead of a list (PHP 8.0–8.2 say “bool given” for false).
  • It depends on the data at that moment, so only the error log shows it.
  • The developer fix: if ( is_iterable( $items ) ) before the loop.

Frequently asked questions

Is my site broken?

No. PHP skips that one loop and continues. A list of related posts, products or links may be empty where you expected items.

What does “null given” mean?

The variable was empty (null): typically a search that found nothing, or a value that was never saved. “bool given” (on PHP 8.3 and later “false given”) means false, which WordPress functions return when there’s nothing to return.

Why do I only see it since PHP 8?

The message is new in PHP 8, but the problem isn’t: PHP 7.4 wrote “Invalid argument supplied for foreach()” for the same code. If your log has that line, it’s the same plugin and the same fix.

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.