[wp-trac] [WordPress Trac] #64406: PHP 8.x TypeError in wp_delete_object_term_relationships() when taxonomy not registered

WordPress Trac noreply at wordpress.org
Fri Dec 12 05:25:08 UTC 2025


#64406: PHP 8.x TypeError in wp_delete_object_term_relationships() when taxonomy
not registered
--------------------------+-----------------------------
 Reporter:  owolter       |      Owner:  (none)
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  Taxonomy      |    Version:  6.9
 Severity:  normal        |   Keywords:  php8 has-patch
  Focuses:                |
--------------------------+-----------------------------
 # WordPress Core Bug Report

 ## Summary
 PHP 8.x TypeError in `wp_delete_object_term_relationships()` when taxonomy
 is not registered during deletion

 ## Description
 The function `wp_delete_object_term_relationships()` in `wp-
 includes/taxonomy.php` does not check if `wp_get_object_terms()` returns a
 `WP_Error` object before passing the result to `array_map()`. This causes
 a fatal TypeError in PHP 8.0+ when attempting to delete attachments if a
 taxonomy is not properly registered at the time of the AJAX request.

 ## Steps to Reproduce
 1. Have a WordPress installation with custom attachment taxonomies
 2. Create a scenario where `post_tag` (or another taxonomy) is not
 registered during admin AJAX calls (e.g., through plugin load order
 issues, early AJAX execution)
 3. Attempt to delete a media library item via wp-admin
 4. Fatal error occurs

 ## Expected Behavior
 Attachment deletion should complete successfully even if a taxonomy
 returns a `WP_Error`, or at minimum should fail gracefully with a logged
 error rather than a fatal PHP error.

 ## Actual Behavior
 Fatal TypeError crashes the deletion process:
 ```
 PHP Fatal error: Uncaught TypeError: array_map(): Argument #2 ($array)
 must be of type array, WP_Error given in /wp-includes/taxonomy.php:2002
 Stack trace:
 #0 /wp-includes/taxonomy.php(2002): array_map()
 #1 /wp-includes/post.php(6743): wp_delete_object_term_relationships()
 #2 /wp-includes/post.php(3799): wp_delete_attachment()
 #3 /wp-admin/includes/ajax-actions.php(889): wp_delete_post()
 ```

 ## Technical Details

 **WordPress Version:** 6.9
 **PHP Version:** 8.3 (also affects 8.0, 8.1, 8.2, 8.4)
 **File:** `wp-includes/taxonomy.php`
 **Line:** ~2002
 **Function:** `wp_delete_object_term_relationships()`

 ### Root Cause
 The WordPress Codex documents that `wp_get_object_terms()` can return
 `WP_Error`, but `wp_delete_object_term_relationships()` assumes it always
 returns an array. In PHP 7.x this would fail silently or produce a
 warning, but PHP 8.x's strict type checking for built-in functions makes
 this a fatal error.

 **Current code (lines 1999-2003):**
 ```php
 foreach ( (array) $taxonomies as $taxonomy ) {
     $term_ids = wp_get_object_terms( $object_id, $taxonomy, array(
 'fields' => 'ids' ) );
     $term_ids = array_map( 'intval', $term_ids );
     wp_remove_object_terms( $object_id, $term_ids, $taxonomy );
 }
 ```

 ## Proposed Fix
 Add a `WP_Error` check before calling `array_map()`:

 ```php
 foreach ( (array) $taxonomies as $taxonomy ) {
     $term_ids = wp_get_object_terms( $object_id, $taxonomy, array(
 'fields' => 'ids' ) );
     if ( is_wp_error( $term_ids ) ) {
         continue;
     }
     $term_ids = array_map( 'intval', $term_ids );
     wp_remove_object_terms( $object_id, $term_ids, $taxonomy );
 }
 ```

 Alternatively, for better debugging:
 ```php
 foreach ( (array) $taxonomies as $taxonomy ) {
     $term_ids = wp_get_object_terms( $object_id, $taxonomy, array(
 'fields' => 'ids' ) );
     if ( is_wp_error( $term_ids ) ) {
         // Log error but continue deletion process
         error_log( sprintf(
             'Error retrieving terms for taxonomy "%s" on object %d: %s',
             $taxonomy,
             $object_id,
             $term_ids->get_error_message()
         ) );
         continue;
     }
     $term_ids = array_map( 'intval', $term_ids );
     wp_remove_object_terms( $object_id, $term_ids, $taxonomy );
 }
 ```

 ## Impact
 This is a **defensive programming issue**. While the underlying cause
 (taxonomy not registered) may vary by installation, WordPress core should
 handle `WP_Error` returns from its own functions gracefully rather than
 causing fatal errors. This affects PHP 8.0+ users and will become more
 prevalent as PHP 7.x reaches end-of-life.

 ## Additional Context
 This issue was discovered when attempting to delete media library items on
 a WordPress 6.9 installation running PHP 8.3. The error occurred because
 `post_tag` taxonomy was not registered during the AJAX deletion request,
 causing `wp_get_object_terms()` to return a `WP_Error` with the message
 "Invalid taxonomy".

 While the specific trigger may be environment-dependent, the lack of error
 handling is a core issue that should be addressed for PHP 8.x
 compatibility and general code robustness.

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


More information about the wp-trac mailing list