Skip to content

Reminder background job crashes for messages with reactionsΒ #18425

Description

@9joshua

Tip

How to use GitHub

  • Please use the πŸ‘ reaction to show that you are affected by the same issue.
  • Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
  • Subscribe to receive notifications on status change and new comments.

Steps to reproduce

  1. In a conversation, post a message and add an emoji reaction to it.
  2. On that same message, set a reminder (message menu β†’ "Set reminder") for a time a few minutes in the future.
  3. Let the reminder time pass and allow background cron to run (or run cron.php manually).

Expected behaviour

The reminder fires, the user receives a notification, and the OCA\Talk\BackgroundJob\Reminder job completes without error.

Actual behaviour

The Reminder background job throws a TypeError on every cron run and never delivers the reminder:

OC\Comments\Comment::setReactions(): Argument #1 ($reactions) must be of type ?array, string given, called in lib/private/Comments/Comment.php on line 482

Because ReminderService::executeReminders() loads all due reminders in a single getMessagesById() call, one reacted message aborts the whole batch β€” so every pending reminder is blocked, and the same error is logged each cron interval, until the offending reminder is removed from the database. The Talk chat UI is unaffected; only the reminder cron path fails.

Talk app

Talk app version: 23.0.6

Server configuration

Operating system: Ubuntu

Web server: Apache

Database: MySQL

PHP version: 8.2

Nextcloud Version: 33.0.5 (Hub 26 Winter)

Server log (data/nextcloud.log)

Details
{"reqId":"Ajgvzs5TUpH8c2YvhCOa","level":3,"time":"2026-06-25T01:52:50+00:00","remoteAddr":"","user":"--","app":"core","method":"","url":"--","scriptName":"…/cron.php","message":"Error while running background job OCA\\Talk\\BackgroundJob\\Reminder (id: 11148, arguments: null)","version":"33.0.5.1","exception":{"Exception":"TypeError","Message":"OC\\Comments\\Comment::setReactions(): Argument #1 ($reactions) must be of type ?array, string given, called in …/lib/private/Comments/Comment.php on line 482","Code":0,"Trace":[{"file":"…/lib/private/Comments/Comment.php","line":482,"function":"setReactions","class":"OC\\Comments\\Comment","type":"->"},{"file":"…/lib/private/Comments/Comment.php","line":42,"function":"fromArray","class":"OC\\Comments\\Comment","type":"->"},{"file":"…/apps/spreed/lib/Chat/CommentsManager.php","line":25,"function":"__construct","class":"OC\\Comments\\Comment","type":"->"},{"file":"…/apps/spreed/lib/Chat/CommentsManager.php","line":46,"function":"getCommentFromData","class":"OCA\\Talk\\Chat\\CommentsManager","type":"->"},{"file":"…/apps/spreed/lib/Chat/ChatManager.php","line":1234,"function":"getCommentsById","class":"OCA\\Talk\\Chat\\CommentsManager","type":"->"},{"file":"…/apps/spreed/lib/Service/ReminderService.php","line":121,"function":"getMessagesById","class":"OCA\\Talk\\Chat\\ChatManager","type":"->"},{"file":"…/apps/spreed/lib/BackgroundJob/Reminder.php","line":31,"function":"executeReminders","class":"OCA\\Talk\\Service\\ReminderService","type":"->"}],"File":"…/lib/private/Comments/Comment.php","Line":449}}

Analysis (root cause)

The crash is in OCA\Talk\Chat\CommentsManager::getCommentFromData(). It builds an OC\Comments\Comment from the raw DB row:

public function getCommentFromData(array $data): IComment {
    $message = $data['message'];
    unset($data['message']);
    $comment = new Comment($this->normalizeDatabaseData($data));   // <-- reactions still a JSON string here on NC 33
    $comment->setMessage($message, ChatManager::MAX_CHAT_LENGTH);
    return $comment;
}

On Nextcloud 33, the reactions column is not decoded into an array by the time it reaches the Comment constructor, so the raw JSON string (e.g. {"πŸ‘":1}) is passed to OC\Comments\Comment::setReactions(), which is typed ?array β†’ TypeError.

It is selective by design:

  • reactions = NULL β†’ setReactions(null) is accepted (most messages).
  • reactions = '{"πŸ‘":1}' (string) β†’ throws.

This is why only the reminder path dies: it loads messages by ID via getCommentsById(), whereas normal chat rendering goes through a path where reactions are decoded. The file already contains a FIXME referencing the in-flight core comments refactor (nextcloud/server#53896), which looks related.

No released spreed version through 23.0.6 fixes this.

Proposed fix

Decode the JSON columns to arrays before constructing the comment (guarded so it's a no-op if a future change starts decoding them upstream):

$data = $this->normalizeDatabaseData($data);
if (isset($data['reactions']) && is_string($data['reactions'])) {
    $data['reactions'] = json_decode($data['reactions'], true) ?: [];
}
if (isset($data['meta_data']) && is_string($data['meta_data'])) {
    $data['meta_data'] = json_decode($data['meta_data'], true) ?: [];
}
$comment = new Comment($data);

Confirmed locally: with this change the reminder job completes and delivers reminders on reacted messages.

Workaround (for others hitting this)

Until a fix ships, clear the trigger in the database (cancels the affected pending reminders; messages/reactions are untouched):

DELETE r FROM oc_talk_reminders r
JOIN oc_comments c ON c.id = r.message_id
WHERE c.reactions IS NOT NULL AND c.reactions <> '';

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions