ActionView::Template::Error (undefined method `mentions_container' for nil:NilClass)

I have a user who always gets a 500 error when requesting the “mentioned in comment” notifications:

[2023-04-05T20:53:59] INFO  PID-870 TID-13140 Rails: Started GET "/notifications?type=mentioned_in_comment" for 2003:d0:2746:5f00:4c5e:1201:d005:c8c5 at 2023-04-05 20:53:59 +0000
[2023-04-05T20:53:59] INFO  PID-870 TID-13140 ActionController::Base: Processing by NotificationsController#index as HTML
[2023-04-05T20:53:59] INFO  PID-870 TID-13140 ActionController::Base:   Parameters: {"type"=>"mentioned_in_comment"}
[2023-04-05T20:54:00] INFO  PID-870 TID-13140 ActionController::Base: Completed 500 Internal Server Error in 1175ms (ActiveRecord: 1132.9ms | Allocations: 29469)
[2023-04-05T20:54:00] FATAL PID-870 TID-13140 Rails:   
ActionView::Template::Error (undefined method `mentions_container' for nil:NilClass):
    11:   .media-object.pull-left
    12:     = person_image_link note.actors.first, :size => :thumb_small, :class => 'hovercardable'
    13:   .media-body
    14:     = notification_message_for(note)
    15:     %div
    16:       = timeago(note.updated_at)

app/models/notifications/mentioned.rb:8:in `linked_object'
app/helpers/notifications_helper.rb:12:in `object_link'
app/helpers/notifications_helper.rb:77:in `notification_message_for'
app/views/notifications/_notification.haml:14
app/views/notifications/index.html.haml:71
app/views/notifications/index.html.haml:70:in `each'
app/views/notifications/index.html.haml:70
app/views/notifications/index.html.haml:58:in `each'
app/views/notifications/index.html.haml:58

Is there a way to resolve this?

Thanks.

Hm, that’s weird, because if a Mention is deleted, it should also delete all the notifications for it. So unless you manually deleted a Mention in a Rails console with .delete, that shouldn’t be a valid state. :confused:

Can you open a PostgreSQL shell, and run

SELECT count(*)
FROM notifications
LEFT OUTER JOIN mentions
ON mentions.id = notifications.target_id
WHERE
  notifications.target_type = 'Notifications::MentionedInComment'
  AND mentions.id IS NULL;

To check if this only affects one mention, or multiple?

I’m running MariaDB:

MariaDB [diaspora_production]> SELECT count(*)
    -> FROM notifications
    -> LEFT OUTER JOIN mentions
    -> ON mentions.id = notifications.target_id
    -> WHERE
    ->   notifications.target_type = 'Notifications::MentionedInComment'
    ->   AND mentions.id IS NULL;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.000 sec)

Sorry, brainfart. The right query should be

SELECT count(*)
FROM notifications
LEFT OUTER JOIN mentions
ON mentions.id = notifications.target_id
WHERE
  notifications.type = 'Notifications::MentionedInComment'
  AND mentions.id IS NULL;

That makes more sense!

MariaDB [diaspora_production]> SELECT count(*)
    -> FROM notifications
    -> LEFT OUTER JOIN mentions
    -> ON mentions.id = notifications.target_id
    -> WHERE
    ->   notifications.type = 'Notifications::MentionedInComment'
    ->   AND mentions.id IS NULL;
+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.484 sec)

Hm, odd. But at least it’s only one. You can get the ID of the broken notification with

SELECT notifications.id
FROM notifications
LEFT OUTER JOIN mentions
ON mentions.id = notifications.target_id
WHERE
  notifications.type = 'Notifications::MentionedInComment'
  AND mentions.id IS NULL;

Then, enter the diaspora folder, start a rails console with RAILS_ENV=production bin/rails c, and run

Notification.find(12345).destroy!

That will remove the broken notification, and the user should be able to look at their notifications again. Hard to say what went wrong that the system ended up in that state in the first place, but oh well.

Thanks! Really appreciate your help.