Error fix · Developer errors

PHP Fatal error: Uncaught TypeError - Causes and Fixes

Fix PHP's Uncaught TypeError by reading the message: wrong argument or return type, null passed to a function, or unsupported operands after a PHP 8 upgrade.

Error messagePHP Fatal error: Uncaught TypeError

By SiteDownCheck Editorial · Updated November 4, 2026 · 4 min read

Uncaught TypeError is a PHP fatal error thrown when a value has the wrong type for the operation. It turns up most often after upgrading to PHP 8, when behavior that PHP 7 tolerated became a hard error. Because it is fatal, the request stops and visitors typically see a blank page or a 500 error.

A typical log entry:

PHP Fatal error:  Uncaught TypeError: strlen(): Argument #1 ($string) must be of type string, null given in /var/www/app/helpers.php:88
Stack trace:
#0 /var/www/app/helpers.php(88): strlen(NULL)
#1 /var/www/app/page.php(12): format_title(NULL)
#2 {main}
  thrown in /var/www/app/helpers.php on line 88

Read it from the top. The first line says what function was called, which argument was wrong, the expected type and the type actually received. The stack trace shows who called whom; the bug is usually one or two frames up, where the bad value came from.

The usual message shapes

  • Argument #N ($name) must be of type X, Y given. A function or method got the wrong type. Often null given where a string, array or int is required.
  • Return value must be of type X, Y returned. A function with a return type declaration returned something else, commonly null or false.
  • Unsupported operand types: string + int or array + int. Arithmetic on a non-numeric value.
  • count(): Argument #1 ($value) must be of type Countable|array, null given. In PHP 7 count(null) gave a warning; in 8 it is an error.
  • Cannot access offset of type X on string or Cannot assign ... to property of type. Typed properties and array offsets.
  • Call to a member function x() on null is a different error; see PHP call to a member function on null.

Why it appears after upgrading PHP

PHP 8.0 made many internal functions throw TypeError for invalid argument types, where they previously returned null or warned. PHP 8.1 added deprecations for passing null to non-nullable parameters of built-in functions, which will become errors in a future version. If an old plugin, theme or library has not been updated, it may hit these.

Check the exact version first:

php -v
php -r 'echo PHP_VERSION, PHP_EOL;'

The web server may use a different PHP than the command line; confirm with phpinfo() or your control panel.

Fix it in order

1. Locate the value's origin

Follow the stack trace to the call that created the bad value. Common sources are $_GET/$_POST fields that are missing, database rows that returned null, JSON that decoded to null because it was invalid, and functions returning false on failure.

Validate JSON input before using it with the JSON Validator, and check json_last_error_msg() in your code.

2. Guard the input

$title = $row['title'] ?? '';          // null coalescing
$len   = strlen((string) $title);      // explicit cast when empty is acceptable
$items = is_array($items) ? $items : [];
$total = count($items);

Casting hides bugs if used everywhere, so prefer fixing the data source. For user input, validate and return a proper 400 response when a field is missing.

3. Fix the declared types

If a function can return null, declare it:

function findUser(int $id): ?User
{
    return $this->repo->find($id);   // may be null
}

With declare(strict_types=1); PHP no longer coerces "5" to 5 for scalar arguments, so type errors appear sooner. That is useful in new code, but add it to old code gradually.

4. Update third-party code

If the trace ends inside a plugin or vendor folder, update it with Composer or the vendor's release. If no PHP 8-compatible version exists, replace the package. Rolling back PHP is a temporary measure only.

composer outdated
composer update vendor/package

5. WordPress sites

On WordPress, the file in the trace tells you which plugin or theme is at fault. Rename its folder under wp-content/plugins to deactivate it and reload. See WordPress plugin conflict troubleshooting and critical error on this website.

Catch it, log it, and keep the site up

You can catch TypeError like any exception:

try {
    $result = compute($value);
} catch (TypeError $e) {
    error_log($e->getMessage());
    $result = null;
}

Use this for boundaries, such as parsing external data. Do not wrap whole applications in an empty catch, because you will lose the signal.

In production, keep display_errors = Off and log_errors = On, so visitors do not see paths and stack traces.

Verify

Reproduce the request that failed, confirm the log has no new TypeError, and check that the status is healthy with the HTTP Status Checker. The Website Health Check catches 500s on key pages, and an Uptime Monitor with keyword checks alerts you if a deploy reintroduces the fatal error. If every request returns 500, also read fix 500 internal server error.

Next steps

FAQ

Why did this start after a hosting upgrade?

The host likely moved you to PHP 8, where type checks on built-in functions are stricter. Update your code and plugins, or ask the host for the previous version while you fix it.

Can I just suppress it?

You can catch the exception, but the underlying bad value will cause problems elsewhere. Fix the source.

What is the difference between TypeError and a warning?

A warning lets the script continue. A TypeError is thrown as an exception and ends the request unless caught.

Should I enable strict_types?

For new code, yes. It surfaces type bugs early. Retrofit old code carefully.

Get notified when this fix updates

Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.

This page is general information written by our editorial team and updated when documentation changes. Servers and providers differ, so test changes safely first. See our editorial policy and disclaimer.