We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Notitications was not showing followers, now it's not showing anything and the notification page shows "System error"
**Describe the bug**
The notification page is not working. When I see that there's a new notification (with a number close to the bell icon), I click on it. Then I get "System error" 
<img width="672" alt="Screenshot 2024-01-05 at 10 30 20" src="https://github.com/bookwyrm-social/bookwyrm/assets/6791923/4cd46e03-6b50-4679-b8a0-61fdb50570a8">
<img width="456" alt="Screenshot 2024-01-05 at 10 30 08" src="https://github.com/bookwyrm-social/bookwyrm/assets/6791923/2130a984-9ed1-4a77-92b3-9dd63fa9c41f">

**Instance**

https://books.babb.no

**Additional context**
Before this happened, the notifications for new following requests were not showing on the list of notifications. A follow request would trigger the update on the number of new notifications, but the notification itself wasn't showing on the list of notifications




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bookwyrm/templatetags/utilities.py`
Content:
```
1 """ template filters for really common utilities """
2 import os
3 import re
4 from uuid import uuid4
5 from urllib.parse import urlparse
6 from django import template
7 from django.utils.safestring import mark_safe
8 from django.utils.translation import gettext_lazy as _
9 from django.templatetags.static import static
10 
11 from bookwyrm.models import User
12 from bookwyrm.settings import INSTANCE_ACTOR_USERNAME
13 
14 register = template.Library()
15 
16 
17 @register.filter(name="uuid")
18 def get_uuid(identifier):
19     """for avoiding clashing ids when there are many forms"""
20     return f"{identifier}{uuid4()}"
21 
22 
23 @register.simple_tag(takes_context=False)
24 def join(*args):
25     """concatenate an arbitrary set of values"""
26     return "_".join(str(a) for a in args)
27 
28 
29 @register.filter(name="username")
30 def get_user_identifier(user):
31     """use localname for local users, username for remote"""
32     return user.localname if user.localname else user.username
33 
34 
35 @register.filter(name="user_from_remote_id")
36 def get_user_identifier_from_remote_id(remote_id):
37     """get the local user id from their remote id"""
38     user = User.objects.get(remote_id=remote_id)
39     return user if user else None
40 
41 
42 @register.filter(name="book_title")
43 def get_title(book, too_short=5):
44     """display the subtitle if the title is short"""
45     if not book:
46         return ""
47     title = book.title
48     if len(title) <= too_short and book.subtitle:
49         title = _("%(title)s: %(subtitle)s") % {
50             "title": title,
51             "subtitle": book.subtitle,
52         }
53     return title
54 
55 
56 @register.simple_tag(takes_context=False)
57 def comparison_bool(str1, str2, reverse=False):
58     """idk why I need to write a tag for this, it returns a bool"""
59     if reverse:
60         return str1 != str2
61     return str1 == str2
62 
63 
64 @register.filter(is_safe=True)
65 def truncatepath(value, arg):
66     """Truncate a path by removing all directories except the first and truncating"""
67     path = os.path.normpath(value.name)
68     path_list = path.split(os.sep)
69     try:
70         length = int(arg)
71     except ValueError:  # invalid literal for int()
72         return path_list[-1]  # Fail silently.
73     return f"{path_list[0]}/…{path_list[-1][-length:]}"
74 
75 
76 @register.simple_tag(takes_context=False)
77 def get_book_cover_thumbnail(book, size="medium", ext="jpg"):
78     """Returns a book thumbnail at the specified size and extension,
79     with fallback if needed"""
80     if size == "":
81         size = "medium"
82     try:
83         cover_thumbnail = getattr(book, f"cover_bw_book_{size}_{ext}")
84         return cover_thumbnail.url
85     except OSError:
86         return static("images/no_cover.jpg")
87 
88 
89 @register.filter(name="get_isni_bio")
90 def get_isni_bio(existing, author):
91     """Returns the isni bio string if an existing author has an isni listed"""
92     auth_isni = re.sub(r"\D", "", str(author.isni))
93     if len(existing) == 0:
94         return ""
95     for value in existing:
96         if hasattr(value, "bio") and auth_isni == re.sub(r"\D", "", str(value.isni)):
97             return mark_safe(f"Author of <em>{value.bio}</em>")
98 
99     return ""
100 
101 
102 # pylint: disable=unused-argument
103 @register.filter(name="get_isni", needs_autoescape=True)
104 def get_isni(existing, author, autoescape=True):
105     """Returns the isni ID if an existing author has an ISNI listing"""
106     auth_isni = re.sub(r"\D", "", str(author.isni))
107     if len(existing) == 0:
108         return ""
109     for value in existing:
110         if hasattr(value, "isni") and auth_isni == re.sub(r"\D", "", str(value.isni)):
111             isni = value.isni
112             return mark_safe(
113                 f'<input type="text" name="isni-for-{author.id}" value="{isni}" hidden>'
114             )
115     return ""
116 
117 
118 @register.simple_tag(takes_context=False)
119 def id_to_username(user_id):
120     """given an arbitrary remote id, return the username"""
121     if user_id:
122         url = urlparse(user_id)
123         domain = url.netloc
124         parts = url.path.split("/")
125         name = parts[-1]
126         value = f"{name}@{domain}"
127 
128     return value
129 
130 
131 @register.filter(name="get_file_size")
132 def get_file_size(file):
133     """display the size of a file in human readable terms"""
134 
135     try:
136         raw_size = os.stat(file.path).st_size
137         if raw_size < 1024:
138             return f"{raw_size} bytes"
139         if raw_size < 1024**2:
140             return f"{raw_size/1024:.2f} KB"
141         if raw_size < 1024**3:
142             return f"{raw_size/1024**2:.2f} MB"
143         return f"{raw_size/1024**3:.2f} GB"
144     except Exception:  # pylint: disable=broad-except
145         return ""
146 
147 
148 @register.filter(name="get_user_permission")
149 def get_user_permission(user):
150     """given a user, return their permission level"""
151 
152     return user.groups.first() or "User"
153 
154 
155 @register.filter(name="is_instance_admin")
156 def is_instance_admin(localname):
157     """Returns a boolean indicating whether the user is the instance admin account"""
158     return localname == INSTANCE_ACTOR_USERNAME
159
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/bookwyrm/templatetags/utilities.py b/bookwyrm/templatetags/utilities.py
--- a/bookwyrm/templatetags/utilities.py
+++ b/bookwyrm/templatetags/utilities.py
@@ -125,7 +125,8 @@
         name = parts[-1]
         value = f"{name}@{domain}"
 
-    return value
+        return value
+    return "a new user account"
 
 
 @register.filter(name="get_file_size")

{"golden_diff": "diff --git a/bookwyrm/templatetags/utilities.py b/bookwyrm/templatetags/utilities.py\n--- a/bookwyrm/templatetags/utilities.py\n+++ b/bookwyrm/templatetags/utilities.py\n@@ -125,7 +125,8 @@\n         name = parts[-1]\n         value = f\"{name}@{domain}\"\n \n-    return value\n+        return value\n+    return \"a new user account\"\n \n \n @register.filter(name=\"get_file_size\")\n", "issue": "Notitications was not showing followers, now it's not showing anything and the notification page shows \"System error\"\n**Describe the bug**\r\nThe notification page is not working. When I see that there's a new notification (with a number close to the bell icon), I click on it. Then I get \"System error\" \r\n<img width=\"672\" alt=\"Screenshot 2024-01-05 at 10 30 20\" src=\"https://github.com/bookwyrm-social/bookwyrm/assets/6791923/4cd46e03-6b50-4679-b8a0-61fdb50570a8\">\r\n<img width=\"456\" alt=\"Screenshot 2024-01-05 at 10 30 08\" src=\"https://github.com/bookwyrm-social/bookwyrm/assets/6791923/2130a984-9ed1-4a77-92b3-9dd63fa9c41f\">\r\n\r\n**Instance**\r\n\r\nhttps://books.babb.no\r\n\r\n**Additional context**\r\nBefore this happened, the notifications for new following requests were not showing on the list of notifications. A follow request would trigger the update on the number of new notifications, but the notification itself wasn't showing on the list of notifications\r\n\r\n\r\n\n", "before_files": [{"content": "\"\"\" template filters for really common utilities \"\"\"\nimport os\nimport re\nfrom uuid import uuid4\nfrom urllib.parse import urlparse\nfrom django import template\nfrom django.utils.safestring import mark_safe\nfrom django.utils.translation import gettext_lazy as _\nfrom django.templatetags.static import static\n\nfrom bookwyrm.models import User\nfrom bookwyrm.settings import INSTANCE_ACTOR_USERNAME\n\nregister = template.Library()\n\n\n@register.filter(name=\"uuid\")\ndef get_uuid(identifier):\n    \"\"\"for avoiding clashing ids when there are many forms\"\"\"\n    return f\"{identifier}{uuid4()}\"\n\n\n@register.simple_tag(takes_context=False)\ndef join(*args):\n    \"\"\"concatenate an arbitrary set of values\"\"\"\n    return \"_\".join(str(a) for a in args)\n\n\n@register.filter(name=\"username\")\ndef get_user_identifier(user):\n    \"\"\"use localname for local users, username for remote\"\"\"\n    return user.localname if user.localname else user.username\n\n\n@register.filter(name=\"user_from_remote_id\")\ndef get_user_identifier_from_remote_id(remote_id):\n    \"\"\"get the local user id from their remote id\"\"\"\n    user = User.objects.get(remote_id=remote_id)\n    return user if user else None\n\n\n@register.filter(name=\"book_title\")\ndef get_title(book, too_short=5):\n    \"\"\"display the subtitle if the title is short\"\"\"\n    if not book:\n        return \"\"\n    title = book.title\n    if len(title) <= too_short and book.subtitle:\n        title = _(\"%(title)s: %(subtitle)s\") % {\n            \"title\": title,\n            \"subtitle\": book.subtitle,\n        }\n    return title\n\n\n@register.simple_tag(takes_context=False)\ndef comparison_bool(str1, str2, reverse=False):\n    \"\"\"idk why I need to write a tag for this, it returns a bool\"\"\"\n    if reverse:\n        return str1 != str2\n    return str1 == str2\n\n\n@register.filter(is_safe=True)\ndef truncatepath(value, arg):\n    \"\"\"Truncate a path by removing all directories except the first and truncating\"\"\"\n    path = os.path.normpath(value.name)\n    path_list = path.split(os.sep)\n    try:\n        length = int(arg)\n    except ValueError:  # invalid literal for int()\n        return path_list[-1]  # Fail silently.\n    return f\"{path_list[0]}/\u2026{path_list[-1][-length:]}\"\n\n\n@register.simple_tag(takes_context=False)\ndef get_book_cover_thumbnail(book, size=\"medium\", ext=\"jpg\"):\n    \"\"\"Returns a book thumbnail at the specified size and extension,\n    with fallback if needed\"\"\"\n    if size == \"\":\n        size = \"medium\"\n    try:\n        cover_thumbnail = getattr(book, f\"cover_bw_book_{size}_{ext}\")\n        return cover_thumbnail.url\n    except OSError:\n        return static(\"images/no_cover.jpg\")\n\n\n@register.filter(name=\"get_isni_bio\")\ndef get_isni_bio(existing, author):\n    \"\"\"Returns the isni bio string if an existing author has an isni listed\"\"\"\n    auth_isni = re.sub(r\"\\D\", \"\", str(author.isni))\n    if len(existing) == 0:\n        return \"\"\n    for value in existing:\n        if hasattr(value, \"bio\") and auth_isni == re.sub(r\"\\D\", \"\", str(value.isni)):\n            return mark_safe(f\"Author of <em>{value.bio}</em>\")\n\n    return \"\"\n\n\n# pylint: disable=unused-argument\n@register.filter(name=\"get_isni\", needs_autoescape=True)\ndef get_isni(existing, author, autoescape=True):\n    \"\"\"Returns the isni ID if an existing author has an ISNI listing\"\"\"\n    auth_isni = re.sub(r\"\\D\", \"\", str(author.isni))\n    if len(existing) == 0:\n        return \"\"\n    for value in existing:\n        if hasattr(value, \"isni\") and auth_isni == re.sub(r\"\\D\", \"\", str(value.isni)):\n            isni = value.isni\n            return mark_safe(\n                f'<input type=\"text\" name=\"isni-for-{author.id}\" value=\"{isni}\" hidden>'\n            )\n    return \"\"\n\n\n@register.simple_tag(takes_context=False)\ndef id_to_username(user_id):\n    \"\"\"given an arbitrary remote id, return the username\"\"\"\n    if user_id:\n        url = urlparse(user_id)\n        domain = url.netloc\n        parts = url.path.split(\"/\")\n        name = parts[-1]\n        value = f\"{name}@{domain}\"\n\n    return value\n\n\n@register.filter(name=\"get_file_size\")\ndef get_file_size(file):\n    \"\"\"display the size of a file in human readable terms\"\"\"\n\n    try:\n        raw_size = os.stat(file.path).st_size\n        if raw_size < 1024:\n            return f\"{raw_size} bytes\"\n        if raw_size < 1024**2:\n            return f\"{raw_size/1024:.2f} KB\"\n        if raw_size < 1024**3:\n            return f\"{raw_size/1024**2:.2f} MB\"\n        return f\"{raw_size/1024**3:.2f} GB\"\n    except Exception:  # pylint: disable=broad-except\n        return \"\"\n\n\n@register.filter(name=\"get_user_permission\")\ndef get_user_permission(user):\n    \"\"\"given a user, return their permission level\"\"\"\n\n    return user.groups.first() or \"User\"\n\n\n@register.filter(name=\"is_instance_admin\")\ndef is_instance_admin(localname):\n    \"\"\"Returns a boolean indicating whether the user is the instance admin account\"\"\"\n    return localname == INSTANCE_ACTOR_USERNAME\n", "path": "bookwyrm/templatetags/utilities.py"}], "after_files": [{"content": "\"\"\" template filters for really common utilities \"\"\"\nimport os\nimport re\nfrom uuid import uuid4\nfrom urllib.parse import urlparse\nfrom django import template\nfrom django.utils.safestring import mark_safe\nfrom django.utils.translation import gettext_lazy as _\nfrom django.templatetags.static import static\n\nfrom bookwyrm.models import User\nfrom bookwyrm.settings import INSTANCE_ACTOR_USERNAME\n\nregister = template.Library()\n\n\n@register.filter(name=\"uuid\")\ndef get_uuid(identifier):\n    \"\"\"for avoiding clashing ids when there are many forms\"\"\"\n    return f\"{identifier}{uuid4()}\"\n\n\n@register.simple_tag(takes_context=False)\ndef join(*args):\n    \"\"\"concatenate an arbitrary set of values\"\"\"\n    return \"_\".join(str(a) for a in args)\n\n\n@register.filter(name=\"username\")\ndef get_user_identifier(user):\n    \"\"\"use localname for local users, username for remote\"\"\"\n    return user.localname if user.localname else user.username\n\n\n@register.filter(name=\"user_from_remote_id\")\ndef get_user_identifier_from_remote_id(remote_id):\n    \"\"\"get the local user id from their remote id\"\"\"\n    user = User.objects.get(remote_id=remote_id)\n    return user if user else None\n\n\n@register.filter(name=\"book_title\")\ndef get_title(book, too_short=5):\n    \"\"\"display the subtitle if the title is short\"\"\"\n    if not book:\n        return \"\"\n    title = book.title\n    if len(title) <= too_short and book.subtitle:\n        title = _(\"%(title)s: %(subtitle)s\") % {\n            \"title\": title,\n            \"subtitle\": book.subtitle,\n        }\n    return title\n\n\n@register.simple_tag(takes_context=False)\ndef comparison_bool(str1, str2, reverse=False):\n    \"\"\"idk why I need to write a tag for this, it returns a bool\"\"\"\n    if reverse:\n        return str1 != str2\n    return str1 == str2\n\n\n@register.filter(is_safe=True)\ndef truncatepath(value, arg):\n    \"\"\"Truncate a path by removing all directories except the first and truncating\"\"\"\n    path = os.path.normpath(value.name)\n    path_list = path.split(os.sep)\n    try:\n        length = int(arg)\n    except ValueError:  # invalid literal for int()\n        return path_list[-1]  # Fail silently.\n    return f\"{path_list[0]}/\u2026{path_list[-1][-length:]}\"\n\n\n@register.simple_tag(takes_context=False)\ndef get_book_cover_thumbnail(book, size=\"medium\", ext=\"jpg\"):\n    \"\"\"Returns a book thumbnail at the specified size and extension,\n    with fallback if needed\"\"\"\n    if size == \"\":\n        size = \"medium\"\n    try:\n        cover_thumbnail = getattr(book, f\"cover_bw_book_{size}_{ext}\")\n        return cover_thumbnail.url\n    except OSError:\n        return static(\"images/no_cover.jpg\")\n\n\n@register.filter(name=\"get_isni_bio\")\ndef get_isni_bio(existing, author):\n    \"\"\"Returns the isni bio string if an existing author has an isni listed\"\"\"\n    auth_isni = re.sub(r\"\\D\", \"\", str(author.isni))\n    if len(existing) == 0:\n        return \"\"\n    for value in existing:\n        if hasattr(value, \"bio\") and auth_isni == re.sub(r\"\\D\", \"\", str(value.isni)):\n            return mark_safe(f\"Author of <em>{value.bio}</em>\")\n\n    return \"\"\n\n\n# pylint: disable=unused-argument\n@register.filter(name=\"get_isni\", needs_autoescape=True)\ndef get_isni(existing, author, autoescape=True):\n    \"\"\"Returns the isni ID if an existing author has an ISNI listing\"\"\"\n    auth_isni = re.sub(r\"\\D\", \"\", str(author.isni))\n    if len(existing) == 0:\n        return \"\"\n    for value in existing:\n        if hasattr(value, \"isni\") and auth_isni == re.sub(r\"\\D\", \"\", str(value.isni)):\n            isni = value.isni\n            return mark_safe(\n                f'<input type=\"text\" name=\"isni-for-{author.id}\" value=\"{isni}\" hidden>'\n            )\n    return \"\"\n\n\n@register.simple_tag(takes_context=False)\ndef id_to_username(user_id):\n    \"\"\"given an arbitrary remote id, return the username\"\"\"\n    if user_id:\n        url = urlparse(user_id)\n        domain = url.netloc\n        parts = url.path.split(\"/\")\n        name = parts[-1]\n        value = f\"{name}@{domain}\"\n\n        return value\n    return \"a new user account\"\n\n\n@register.filter(name=\"get_file_size\")\ndef get_file_size(file):\n    \"\"\"display the size of a file in human readable terms\"\"\"\n\n    try:\n        raw_size = os.stat(file.path).st_size\n        if raw_size < 1024:\n            return f\"{raw_size} bytes\"\n        if raw_size < 1024**2:\n            return f\"{raw_size/1024:.2f} KB\"\n        if raw_size < 1024**3:\n            return f\"{raw_size/1024**2:.2f} MB\"\n        return f\"{raw_size/1024**3:.2f} GB\"\n    except Exception:  # pylint: disable=broad-except\n        return \"\"\n\n\n@register.filter(name=\"get_user_permission\")\ndef get_user_permission(user):\n    \"\"\"given a user, return their permission level\"\"\"\n\n    return user.groups.first() or \"User\"\n\n\n@register.filter(name=\"is_instance_admin\")\ndef is_instance_admin(localname):\n    \"\"\"Returns a boolean indicating whether the user is the instance admin account\"\"\"\n    return localname == INSTANCE_ACTOR_USERNAME\n", "path": "bookwyrm/templatetags/utilities.py"}]}