Ffile2fix
Sign in Get started

Fix "Uncaught TypeError" in PHP 8

PHP Fatal error:  Uncaught TypeError: calculateTotal(): Argument #1 ($items) must be of type array, null given, called in /var/www/html/cart.php on line 14 and defined in /var/www/html/lib.php:5

A function received, or returned, a value of the wrong type, so PHP threw a TypeError and stopped. PHP 8 made built-in functions strict about this: count(null) or strlen([]) used to give a warning and now end the script. The message names the function, the argument number and the type it got.

Also appears as: Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given · Uncaught TypeError: Unsupported operand types: string + int · Uncaught TypeError: strlen(): Argument #1 ($string) must be of type string, array given · Uncaught TypeError: App\Service::getName(): Return value must be of type string, null returned

Common causes

  • Passing null where an array or string is expected, often from a failed query or missing input
  • Calling count() on null or a scalar, which became a TypeError in PHP 8.0
  • Arithmetic on arrays or objects (Unsupported operand types)
  • A typed function returning null without a nullable return type such as ?string
  • declare(strict_types=1) rejecting a numeric string passed to an int parameter
  • Old plugins or libraries not updated for PHP 8

How to fix it

  1. Read the message parts. Argument #1 ($items) must be of type array, null given names the parameter and the actual type. 'called in ... line 14' is the caller that passed the bad value; 'defined in' is the function itself.
  2. Fix the value at the caller. Find where the variable gets its value and make sure it is the expected type. For example, a database fetch that returns false or null when no rows are found must be handled before passing it on.
  3. Add safe defaults. Use count($items ?? []) or (string) ($value ?? '') where an empty value is acceptable. Use is_array() or is_countable() before calling count() on data you do not control.
  4. Correct type declarations. If null is a valid value, declare the parameter or return as nullable, such as ?array $items = null or : ?string. Use union types like int|string where both are legitimate.
  5. Update outdated code. If the trace points into a plugin, theme or vendor package, update it to a version that supports your PHP version. As a temporary fix, run the site on the older PHP version while you wait for an update.

Defensive fixes

<?php
// Before (TypeError on PHP 8 when $rows is null)
$total = count($rows);

// After
$total = is_countable($rows) ? count($rows) : 0;

// Nullable parameter and return types
function findName(?array $user): ?string {
    return $user['name'] ?? null;
}

How to stop it happening again

  • Run static analysis (PHPStan or Psalm) to catch type mismatches before deployment
  • Return empty arrays instead of null from functions that return lists
  • Test plugins and libraries on your target PHP version before upgrading production
  • Validate external input at the boundary and convert it to the expected types

Frequently asked questions

Why did this start after upgrading to PHP 8?

PHP 8.0 made internal functions throw TypeError for invalid argument types, where PHP 7 only emitted a warning and returned null. Code that silently did the wrong thing now stops.

Can I catch a TypeError?

Yes, with try { ... } catch (\TypeError $e) { ... }. It is useful at boundaries such as API handlers, but fixing the type at the source is better than catching it everywhere.

What does strict_types change?

With declare(strict_types=1) at the top of the calling file, PHP stops converting compatible scalars, so passing "5" to an int parameter throws a TypeError. Without it, PHP converts numeric strings to int automatically.