Skip to content

wp post delete emits 'does not support being sent to trash' warning even when post_type_supports() returns true #618

Description

@crbiz-sysadmin

Steps to reproduce

  1. Register a custom post type with 'trash' in its supports array (or use add_post_type_support() after registration).
  2. Verify the support is registered correctly:
wp eval "echo post_type_supports('mycpt', 'trash') ? 'yes' : 'no';"
# → yes
  1. Attempt to soft-delete a post of that CPT:
wp post delete 1234
# → Warning: Posts of type 'mycpt' do not support being sent to trash.
#   Please use the --force flag to skip trash and delete them permanently.

Expected behaviour

The post is sent to trash (post_status set to trash, _wp_trash_meta_status + _wp_trash_meta_time written), exactly as if you'd clicked the Trash button in WP admin.

Actual behaviour

The command warns that the CPT doesn't support trash and refuses to proceed without --force. --force then hard-deletes, losing the native 30-day reversibility window.

Environment

  • WP-CLI 2.12.0
  • WordPress 6.x (reproduced on multiple recent versions)
  • PHP 8.2

Workaround

Call wp_trash_post() directly via wp eval-file — this is the same WP core function the trash button calls, and it correctly honours post_type_supports(). End state is identical (including the trash-meta keys for native 30-day auto-purge):

echo '<?php  = [1234, 5678]; foreach ( as ) {  = wp_trash_post(); echo "$id: " . ( ? "trashed" : "FAILED") . "\n"; }' > /tmp/trash.php
wp eval-file /tmp/trash.php

Hypothesis (please verify)

Symptom suggests the wp post delete subcommand inspects the WP_Post_Type::$supports instance property directly rather than calling post_type_supports(). WordPress copies that property into the global $_wp_post_type_features array during register_post_type() and then unsets the instance property, so the inspection returns an unexpectedly-missing value at later request times — even though post_type_supports() (which reads from the global array) returns the correct true.

If that hypothesis holds, the fix would be to swap any isset($post_type_object->supports['trash'])-style check inside the delete command for post_type_supports($post_type, 'trash').

Why it matters

Custom post types that have correctly opted in to trash via supports should be deletable to trash via WP-CLI the same way they are via wp-admin. The current behaviour silently nudges operators toward --force (irrecoverable) or workarounds like the wp_trash_post() invocation above.

Happy to provide more environment detail if useful.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions