Skip to content

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

@crbiz-sysadmin

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

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions