Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To stop WordPress authors from deleting posts, remove the role’s delete_posts capability. If published content must remain protected, also remove delete_published_posts. Remove delete_others_posts when the role must not delete posts owned by other users. These permissions are separate from editing and publishing, so authors can continue working on content without being able to remove it.

Which WordPress capabilities control deletion?

WordPress separates editing, publishing, and deletion into individual capabilities. The relevant capabilities are:

Capability What it controls When to remove it
delete_posts Deleting posts generally, normally including the current user’s posts Remove to block an author’s normal post-deletion ability
delete_published_posts Deleting posts that have already been published Remove when published posts must never be deleted by that role
delete_others_posts Deleting posts owned by another user Remove when the role must be limited to its own content
edit_posts Editing posts, generally including drafts Keep if authors should still edit content
edit_published_posts Editing published posts Keep only if authors should revise live content
publish_posts Publishing posts Keep only if authors may publish without review

Removing a deletion capability does not automatically remove editing or publishing capabilities. Conversely, leaving edit_posts enabled does not give a user permission to delete.

Option 1: Remove deletion capabilities in a role-management interface

A role-management plugin is the simplest route when you do not want to edit PHP. A plugin such as PublishPress Capabilities provides an interface for choosing who can publish, read, edit, and delete content, and for creating or copying roles. Check its current WordPress compatibility and licensing before installing it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Back up the site and identify whether the restriction should apply to every Author account or to a separate role.
  2. Open your capability-management plugin and edit the relevant role.
  3. Clear delete_posts.
  4. Clear delete_published_posts if published posts also need protection.
  5. Clear delete_others_posts if users must not remove another author’s posts.
  6. Leave edit_posts, edit_published_posts, and publish_posts enabled only when the workflow requires them.
  7. Save the role, then test with a non-administrator account.

Editing the built-in Author role changes every user assigned to that role. A dedicated role is safer when only one team, department, or workflow needs the restriction.

Option 2: Create a dedicated role in code

Use a small site-specific plugin or a controlled deployment rather than placing permanent policy code in a theme. This example creates a role that can edit drafts, edit published posts, and publish, but has no deletion capabilities:

add_role(
    'managed_author',
    'Managed Author',
    array(
        'read'                  => true,
        'edit_posts'            => true,
        'edit_published_posts'  => true,
        'publish_posts'         => true,
        'delete_posts'          => false,
        'delete_published_posts'=> false,
        'delete_others_posts'   => false,
    )
);

Run role creation during plugin activation or another deliberate deployment step, not on every page request. Assign selected users to managed_author, and remove or update the role deliberately if the policy changes. Adjust the capability list to match your editorial process; for example, omit publish_posts when an editor must approve every article.

Protecting published posts specifically

Drafts and published posts are not the same permission case. An author may be allowed to delete an abandoned draft while being forbidden to remove a live article. To protect published content, remove delete_published_posts even if your role still has other deletion-related permissions.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Also check ownership. delete_others_posts controls deletion of posts belonging to someone else. A custom role or post type may expose that capability even when the normal Author workflow does not, so explicitly clear it when cross-user deletion is unacceptable.

Why disabling Trash is not a permission control

Trash is a recovery workflow, not an authorization boundary. With Trash enabled, wp_delete_post() normally moves an ordinary post to Trash. Permanent deletion can occur when the operation uses $force_delete, when Trash is disabled, or when the item is already in Trash. wp_trash_post() likewise documents that disabling Trash causes permanent deletion.

Therefore, changing Trash settings alone does not stop an author from initiating deletion. Use capabilities to decide who may perform the operation, and keep Trash enabled when you want a recovery window. If permanent removal is required, restrict that action separately and test it carefully.

Option 3: Enforce the rule with WordPress filters

Capability changes are usually sufficient, but a code-level policy can protect against additional entry points such as bulk actions, REST requests, XML-RPC, or custom workflows. The pre_delete_post filter can short-circuit deletion, and pre_trash_post can intercept an attempt to move a post to Trash.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
add_filter('pre_delete_post', function ($delete, $post, $force_delete) {
    if (!$post instanceof WP_Post) {
        return $delete;
    }

    if ($post->post_type === 'post' && !current_user_can('manage_options')) {
        return false;
    }

    return $delete;
}, 10, 3);

add_filter('pre_trash_post', function ($trash, $post, $previous_status) {
    if (!$post instanceof WP_Post) {
        return $trash;
    }

    if ($post->post_type === 'post' && !current_user_can('manage_options')) {
        return false;
    }

    return $trash;
}, 10, 3);

This illustrative policy blocks deletion and trashing of normal posts for users without the manage_options capability. Replace that condition with your actual rule, such as checking the current user, post author, post status, or post type. Returning a non-null value from either filter short-circuits the corresponding operation; test the result in your WordPress version and workflow.

Put enforcement in a small site plugin, and test drafts, published posts, bulk actions, REST requests, and every custom post type. Decide how the editor should see a blocked operation and log failures if the site needs an audit trail.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Custom post types need a separate capability audit

Do not assume a custom post type uses the same permission mapping as standard posts. Inspect its registration:

  • capability_type determines the base capability names WordPress uses.
  • An explicit capabilities array can override names such as delete_posts, delete_published_posts, and delete_others_posts.
  • map_meta_cap affects how object-level checks are resolved for an individual item.

Review the generated capabilities and assign the corresponding custom names in the role. Then test an item owned by the current user, an item owned by another user, a draft, a published item, and a trashed item. A role policy that works for posts may not protect a custom post type unless its mapping is aligned.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Verification checklist

  • Test as the restricted role, not as an administrator.
  • Confirm the user can still perform intended actions such as editing drafts or publishing.
  • Try deleting the user’s own draft.
  • Try deleting the user’s own published post.
  • Try deleting another user’s post.
  • Repeat the tests from list-table bulk actions and the post editor.
  • Test REST or other integrations used by the site.
  • Confirm that Trash behavior matches the recovery policy and that permanent deletion is limited to authorized users.

Choosing the right implementation

Approach Best for Limitation
Role capability changes A site-wide role rule with minimal code Changing the built-in Author role affects every user assigned to it
Dedicated custom role Different rules for different teams or authors Requires deliberate role lifecycle management
Capability-management plugin Administrators who need a UI and role-copying tools Requires maintaining an additional plugin
pre_delete_post and pre_trash_post Per-post, per-status, custom-post-type, or integration-wide enforcement Requires PHP development and thorough testing

The Bottom Line

Remove delete_posts from the relevant role, add delete_published_posts and delete_others_posts restrictions when required, and use the deletion filters when the policy must hold across custom workflows and APIs.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.