# ReactionLikeSynchronizer reprocesses already-trashed PostAction likes every hour

**URL:** <https://meta.discourse.org/t/reactionlikesynchronizer-reprocesses-already-trashed-postaction-likes-every-hour/414539>\
**Category:** Bug\
**Created:** [October 12, 2026, 7:53pm UTC](https://meta.discourse.org/t/reactionlikesynchronizer-reprocesses-already-trashed-postaction-likes-every-hour/414539 "2026-10-12T19:53:06Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![James\_Wong](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/james_wong/32/580729_2.png) [@James\_Wong](https://meta.discourse.org/u/James_Wong)\
**Post date:** [October 12, 2026, 7:53pm UTC](https://meta.discourse.org/t/reactionlikesynchronizer-reprocesses-already-trashed-postaction-likes-every-hour/414539/1 "2026-10-12T19:53:07Z")

</div>

We’ve encountered an issue on a self-hosted Discourse site in which the `ReactionLikeSynchronizer` seems to be triggering 500/504 errors for user actions.

The job appears to be repeatedly trashing the same 26,766 `PostAction` likes every hour, even though all of them have been marked as deleted. During these longer sync runs, normal user requests seem to block in PostgreSQL and hit Pitchfork’s 30-second timeout.

### Environment

- Self-hosted Discourse on version v2026.10.0-latest-277-ge1f6bd561
- PostgreSQL 18.4
- `discourse_reactions_like_sync_enabled = true`
- This is an older site, so there is a lot of historical reaction data

### User Reports

- Reactions sometimes fail and produce a “Something went wrong” message.
- Topics a user visited sometimes remain marked unread
- Reports are clustered around once per hour at the top of the hour.

### Logs and Data

```plaintext
13:58:58 ReactionLikeSynchronizer starts
13:59:50 Pitchfork worker timeout / 500
14:00:02 Pitchfork worker timeout / 500
14:00:18 Pitchfork worker timeout / 500
14:00:48 ReactionLikeSynchronizer completes

```

```plaintext
15:00:09 sync starts
15:01:16 request timeout / 500
15:01:40 request timeout / 500
15:01:45 sync completes

```

#### Synchronizer Output

```plaintext
Inserted 0 post action likes, recovered 0 trashed post action likes. (0 total)
Trashed 26766 post action likes.

```

Notably, the same 26766 count shows up on every run I checked.

#### Database Contents

```plaintext
SELECT
  COUNT(*) AS total,
  COUNT(*) FILTER (WHERE pa.deleted_at IS NULL) AS currently_active,
  COUNT(*) FILTER (WHERE pa.deleted_at IS NOT NULL) AS already_trashed
FROM post_actions pa
JOIN discourse_reactions_reaction_users ru
  ON ru.user_id = pa.user_id
 AND ru.post_id = pa.post_id
JOIN discourse_reactions_reactions r
  ON r.id = ru.reaction_id
WHERE pa.post_action_type_id = 2
  AND r.reaction_value IN (
    '-1','poop','face_with_symbols_on_mouth','enraged_face',
    'face_vomiting','nauseated_face','angry','kitchen_knife',
    'water_pistol','bomb','clown_face','unamused_face','roll_eyes',
    'confused','smirking_face','disappointed_face','pensive_face',
    'lying_face','weary_face','tired_face','confounded_face',
    'persevering_face','smiling_face_with_horns','angry_face_with_horns',
    'cigarette','person_gesturing_no','prohibited','no_entry',
    'dagger','cross_mark'
  );

```

```plaintext
 total | currently_active | already_trashed

-------+------------------+-----------------

 26766 | 0 | 26766

```

### Notes

For what it’s worth, it looks like `ReactionLikeSynchronizer#trash_excluded_post_actions` matches likes that have been excluded even if they have already been deleted. The query looks like this:

```plaintext
UPDATE post_actions
SET deleted_at = NOW()
FROM discourse_reactions_reaction_users ru
INNER JOIN discourse_reactions_reactions
  ON discourse_reactions_reactions.id = ru.reaction_id
WHERE post_actions.user_id = ru.user_id
  AND post_actions.post_id = ru.post_id
  AND post_actions.post_action_type_id = :like
  AND discourse_reactions_reactions.reaction_value IN (:excluded_from_like)
RETURNING post_actions.id

```

Notably, this doesn’t exclude deleted actions via something like `AND post_actions.deleted_at IS NULL`.

This appears to result in the same set of rows being reprocessed every hour. I can add a stack trace, if necessary.

As a workaround, I’ve disabled `discourse_reactions_like_sync_enabled` and am monitoring whether the errors stop occurring every hour.

---

_[View the full topic](https://meta.discourse.org/t/reactionlikesynchronizer-reprocesses-already-trashed-postaction-likes-every-hour/414539)._
