[wp-trac] [WordPress Trac] #64870: Fatal TypeError: urldecode() expects string, array given in formatting.php (PHP 8+)

WordPress Trac noreply at wordpress.org
Tue Mar 17 05:08:18 UTC 2026


#64870: Fatal TypeError: urldecode() expects string, array given in formatting.php
(PHP 8+)
---------------------------+-----------------------------
 Reporter:  patricedefago  |      Owner:  (none)
     Type:  defect (bug)   |     Status:  new
 Priority:  normal         |  Milestone:  Awaiting Review
Component:  Formatting     |    Version:  6.9.1
 Severity:  normal         |   Keywords:  has-patch php8
  Focuses:                 |
---------------------------+-----------------------------
 == Description

 When visiting a URL with array-style GET parameters (e.g.,
 `/?product_cat[]=clothing`), WordPress core throws a fatal `TypeError` in
 `wp-includes/formatting.php` because `urldecode()` receives an array
 instead of a string. This occurs on PHP 8+, which enforces strict type
 checking for built-in functions.

 == Steps to reproduce

 1. Use WordPress 6.9.1 with PHP 8.x
 2. Visit a URL with an array-style query parameter, e.g.:
 `https://example.com/?product_cat[]=clothing`
 3. A fatal error is triggered in `wp-includes/formatting.php`

 == Expected behavior

 The page should load normally. Array GET parameters should be handled
 gracefully (ignored, sanitized, or skipped).

 == Actual behavior

 Fatal error: `TypeError: urldecode(): Argument #1 ($string) must be of
 type string, array given`

 == Environment

 - WordPress: 6.9.1
 - PHP: 8.x
 - Any theme/plugin combination

 == Analysis

 The `urldecode()` call does not check whether the `$_GET` value is an
 array before processing. Since `urldecode()` only accepts strings, passing
 an array (which PHP creates automatically from query strings like
 `param[]=value`) causes a fatal TypeError on PHP 8+. On PHP 7.x, this was
 silently converted, but PHP 8 enforces strict types on internal functions.

 A type check (e.g., `is_array()` or `! is_string()`) before calling
 `urldecode()` would prevent the crash.

 == Related

 - WooCommerce issue with the same root cause:
 https://github.com/woocommerce/woocommerce/issues/63582
 - The WooCommerce-specific instance in `wc-product-functions.php` is being
 fixed separately.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/64870>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list