I noticed in the bulk actions menu (visible on the search page, using bulk select for 1 or more posts).
There are two delete options:
Delete Topic(s)
Delete Post(s)
The confirmation for Delete Posts seems clear, but the confirmation for Delete Topics is confusing imo.
Permanently delete the selected topics. This action cannot be undone.
from: js.topic_bulk_actions.delete_topics.description
If I confirm to delete the selected topic(s), they are deleted normally (soft) and can be restored.
This is with site setting can_permanently_delete as false (default).
Also, there doesn’t seem to be a visual distinction between search results that are a topic or a post/reply, besides hovering over them and looking at the end of the url. Which makes using these two bulk delete options a bit unintuitive for moderators imo.
3 Likes
we’re in the process of improving the “actions” offered in bulk mode, but this one fell through the cracks as it’s not (yet ) available.
main ← fix-bulk-delete-topics-copy
merged 07:46AM - 25 Aug 26 UTC
Reported in [Bulk actions confusion - Delete Topics](https://meta.discourse.org/… t/410444).
Selecting topics and choosing **Delete** asks you to confirm:
> Permanently delete the selected topics. This action cannot be undone.
…and then soft deletes them, so they can be recovered. Not search-specific — the same modal is used by every topic list.
There is no configuration where the copy is true. `TopicsBulkAction#delete` builds `PostDestroyer` with an empty options hash, so `permanent?` is never satisfied, and `PUT /topics/bulk` doesn't permit `force_destroy` in the first place. `can_permanently_delete` has no bearing on this path. The description was added with the copy pass in 4b6169028f and never matched the behaviour.
### Also fixed
Two long-standing bugs in the same six lines:
- `delete` was the only operation in `TopicsBulkAction` that never appended to `@changed_ids`, so the endpoint always answered `{"topic_ids":[]}`. A bulk delete where the guardian skipped every topic looked exactly like a successful one, toast included.
- `ordered_posts` is scoped by `Trashable`, so for a topic whose first post was already deleted it returned post 2. `is_first_post?` was then false, `@topic.trash!` never ran, and an unrelated reply was deleted while the topic stayed alive — reported as a success. `TopicsController#destroy` already gets this right with `ordered_posts.with_deleted.first`.
### Follow-ups, not in this PR
- `ordered_posts.first` feeding `PostDestroyer` carries the same latent bug at five other call sites: `Jobs::DeleteTopic`, three in `DestroyTask`, and `TopicGuardian#can_recover_topic?`. Worth a `Topic` accessor rather than a sixth hand-rolled copy.
- Search results give no hint whether a hit is a topic or a reply, which is the other half of the report. `post_number` is already serialized and `search.post_format` already exists, but is gated to the in-topic dropdown.
- Translations of this key still assert permanence until the pipeline catches up.
3 Likes