WordPress wp_delete_post Example: Remove Content Safely in Code
Delete WordPress content safely in code with trash-versus-force-delete decisions, capability checks, and clear return handling.
Published
April 27, 2026
Reading Time
2 min read
Updated
April 27, 2026

Implementation Notes
Extension points, code paths, and implementation choices that should survive contact with production.
Best For
WordPress developers, agencies, and technical teams building custom plugin or theme functionality with cleaner operational defaults.
Primary Topics
Editorial Focus
Build Pattern: Extension points, code paths, and implementation choices that should survive contact with production. Updated on April 27, 2026.
Full Report
Last reviewed: April 27, 2026
Programmatic deletion needs more care than insertion because deletion can be permanent, can affect related metadata, and may bypass the editorial expectations users have inside wp-admin. The main decision is whether the content should go to trash first or be removed permanently.
This guide shows how to use wp_delete_post() safely, when to force deletion, and where capability checks belong before the delete runs.
Trash first when recovery matters
<?php
if ( ! current_user_can( 'delete_post', $post_id ) ) {
return new WP_Error( 'forbidden', 'You are not allowed to delete this post.' );
}
$deleted = wp_delete_post( $post_id, false );
Passing false as the second argument uses the trash flow when the post type supports it. That is often the safer default for editorial or user-facing content.
Use force delete only when the workflow truly requires it
$deleted = wp_delete_post( $post_id, true );
Force delete skips trash and removes the post immediately. That makes sense for generated temporary content, short-lived staging rows, or cleanup jobs where recovery is not part of the workflow.
Check the return value
The function returns the deleted post object on success or false on failure. Treat that result explicitly instead of assuming the delete always worked.
if ( ! $deleted ) {
return new WP_Error( 'delete_failed', 'Post deletion failed.' );
}
Remember that attachments are special
Attachments have their own deletion path through wp_delete_attachment(). Do not assume wp_delete_post() is the right helper for every media cleanup workflow.
Production checklist
- Authorize the caller before the delete runs.
- Default to trash when the workflow expects recoverability.
- Use force delete only for intentional permanent cleanup.
- Check the return value.
- Use attachment-specific helpers for media deletion flows.
- Document deletion behavior clearly in admin tools and automations.
Common mistakes
- Force deleting editorial content by default. Recovery then becomes much harder.
- No capability check. Delete actions need explicit authorization.
- Ignoring the return value. Failed deletes can look successful in logs or UI.
- Using the same delete strategy for attachments and posts. Media has separate cleanup rules.
- Not aligning deletion with user expectations. Admin tools should make trash versus permanent delete obvious.
Related reading
If the content was created programmatically, pair this with the wp_insert_post guide. If the delete is triggered from an admin form flow, combine it with the admin_post article.


