diff --git a/backend/package-lock.json b/backend/package-lock.json
index c3e38feb..ab298c68 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -24,7 +24,7 @@
         "humanize-duration": "^3.15.0",
         "io-ts": "^2.0.0",
         "js-yaml": "^3.13.1",
-        "knub": "^30.0.0-beta.41",
+        "knub": "^30.0.0-beta.42",
         "knub-command-manager": "^9.1.0",
         "last-commit-log": "^2.1.0",
         "lodash.chunk": "^4.2.0",
@@ -3043,9 +3043,9 @@
       }
     },
     "node_modules/knub": {
-      "version": "30.0.0-beta.41",
-      "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.41.tgz",
-      "integrity": "sha512-tKHGG9vh62ZN0JIi2ULYHvJbR28WXhym8c9vRtyQCPQqJ1w3n7Fow9JXbh6BUTSD8QszWbvq1Ri22wbQtBEyNw==",
+      "version": "30.0.0-beta.42",
+      "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.42.tgz",
+      "integrity": "sha512-y7nqQh1bzQniYwEftdv6S8Jp2qBvT5a7vn+3JeA0s0ADXobI+/rRVznpq8o0x2m0+E+EeKxo1Ch8F8Hy+VMX6w==",
       "dependencies": {
         "discord-api-types": "^0.22.0",
         "discord.js": "^13.0.1",
@@ -8290,9 +8290,9 @@
       }
     },
     "knub": {
-      "version": "30.0.0-beta.41",
-      "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.41.tgz",
-      "integrity": "sha512-tKHGG9vh62ZN0JIi2ULYHvJbR28WXhym8c9vRtyQCPQqJ1w3n7Fow9JXbh6BUTSD8QszWbvq1Ri22wbQtBEyNw==",
+      "version": "30.0.0-beta.42",
+      "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.42.tgz",
+      "integrity": "sha512-y7nqQh1bzQniYwEftdv6S8Jp2qBvT5a7vn+3JeA0s0ADXobI+/rRVznpq8o0x2m0+E+EeKxo1Ch8F8Hy+VMX6w==",
       "requires": {
         "discord-api-types": "^0.22.0",
         "discord.js": "^13.0.1",
diff --git a/backend/package.json b/backend/package.json
index 67724ff9..5ef83427 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -39,7 +39,7 @@
     "humanize-duration": "^3.15.0",
     "io-ts": "^2.0.0",
     "js-yaml": "^3.13.1",
-    "knub": "^30.0.0-beta.41",
+    "knub": "^30.0.0-beta.42",
     "knub-command-manager": "^9.1.0",
     "last-commit-log": "^2.1.0",
     "lodash.chunk": "^4.2.0",
diff --git a/backend/src/plugins/Automod/actions/log.ts b/backend/src/plugins/Automod/actions/log.ts
index b7470427..4a78442d 100644
--- a/backend/src/plugins/Automod/actions/log.ts
+++ b/backend/src/plugins/Automod/actions/log.ts
@@ -19,7 +19,7 @@ export const LogAction = automodAction({
       user,
       users,
       actionsTaken,
-      matchSummary: matchResult.summary,
+      matchSummary: matchResult.summary ?? "",
     });
   },
 });
diff --git a/backend/src/plugins/Cases/CasesPlugin.ts b/backend/src/plugins/Cases/CasesPlugin.ts
index fd6c1e41..5a8c1b45 100644
--- a/backend/src/plugins/Cases/CasesPlugin.ts
+++ b/backend/src/plugins/Cases/CasesPlugin.ts
@@ -16,10 +16,6 @@ import { getRecentCasesByMod } from "./functions/getRecentCasesByMod";
 import { getTotalCasesByMod } from "./functions/getTotalCasesByMod";
 import { postCaseToCaseLogChannel } from "./functions/postToCaseLogChannel";
 import { CaseArgs, CaseNoteArgs, CasesPluginType, ConfigSchema } from "./types";
-import { LogsPlugin } from "../Logs/LogsPlugin";
-
-// Workaround for circular dependency
-const AnyTypedLogsPlugin = LogsPlugin as any;
 
 const defaultOptions = {
   config: {
@@ -42,7 +38,11 @@ export const CasesPlugin = zeppelinGuildPlugin<CasesPluginType>()({
     `),
   },
 
-  dependencies: () => [TimeAndDatePlugin, AnyTypedLogsPlugin],
+  dependencies: async () => [
+    TimeAndDatePlugin,
+    // The `as any` cast here is to prevent TypeScript from locking up from the circular dependency
+    ((await import("../Logs/LogsPlugin")) as any).LogsPlugin,
+  ],
   configSchema: ConfigSchema,
   defaultOptions,
 
diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts
index 69cedd1e..7fe0ea6c 100644
--- a/backend/src/plugins/Logs/LogsPlugin.ts
+++ b/backend/src/plugins/Logs/LogsPlugin.ts
@@ -108,10 +108,6 @@ import { logVoiceChannelLeave } from "./logFunctions/logVoiceChannelLeave";
 import { logVoiceChannelMove } from "./logFunctions/logVoiceChannelMove";
 import { logMemberTimedUnban } from "./logFunctions/logMemberTimedUnban";
 import { logDmFailed } from "./logFunctions/logDmFailed";
-import { CasesPlugin } from "../Cases/CasesPlugin";
-
-// Workaround for circular dependency
-const AnyTypedCasesPlugin = CasesPlugin as any;
 
 const defaultOptions: PluginOptions<LogsPluginType> = {
   config: {
@@ -143,7 +139,11 @@ export const LogsPlugin = zeppelinGuildPlugin<LogsPluginType>()({
     prettyName: "Logs",
   },
 
-  dependencies: () => [TimeAndDatePlugin, AnyTypedCasesPlugin],
+  dependencies: async () => [
+    TimeAndDatePlugin,
+    // The `as any` cast here is to prevent TypeScript from locking up from the circular dependency
+    ((await import("../Cases/CasesPlugin")) as any).CasesPlugin,
+  ],
   configSchema: ConfigSchema,
   defaultOptions,
 
diff --git a/backend/src/plugins/Logs/logFunctions/logAutomodAction.ts b/backend/src/plugins/Logs/logFunctions/logAutomodAction.ts
index 1874f24a..b76194a9 100644
--- a/backend/src/plugins/Logs/logFunctions/logAutomodAction.ts
+++ b/backend/src/plugins/Logs/logFunctions/logAutomodAction.ts
@@ -23,7 +23,7 @@ export function logAutomodAction(pluginData: GuildPluginData<LogsPluginType>, da
       user: userToTemplateSafeUser(data.user),
       users: data.users.map(user => userToTemplateSafeUser(user)),
       actionsTaken: data.actionsTaken,
-      matchSummary: data.matchSummary,
+      matchSummary: data.matchSummary ?? "",
     }),
     {
       userId: data.user.id,
diff --git a/backend/src/plugins/Logs/logFunctions/logMemberRoleAdd.ts b/backend/src/plugins/Logs/logFunctions/logMemberRoleAdd.ts
index 032e5781..bfbc03fc 100644
--- a/backend/src/plugins/Logs/logFunctions/logMemberRoleAdd.ts
+++ b/backend/src/plugins/Logs/logFunctions/logMemberRoleAdd.ts
@@ -17,7 +17,7 @@ export function logMemberRoleAdd(pluginData: GuildPluginData<LogsPluginType>, da
     pluginData,
     LogType.MEMBER_ROLE_ADD,
     createTypedTemplateSafeValueContainer({
-      mod: userToTemplateSafeUser(data.mod),
+      mod: data.mod ? userToTemplateSafeUser(data.mod) : null,
       member: memberToTemplateSafeMember(data.member),
       roles: data.roles.map(r => r.name).join(", "),
     }),
diff --git a/backend/src/plugins/Logs/logFunctions/logMemberRoleRemove.ts b/backend/src/plugins/Logs/logFunctions/logMemberRoleRemove.ts
index 98a7acdb..a32f9cd9 100644
--- a/backend/src/plugins/Logs/logFunctions/logMemberRoleRemove.ts
+++ b/backend/src/plugins/Logs/logFunctions/logMemberRoleRemove.ts
@@ -17,7 +17,7 @@ export function logMemberRoleRemove(pluginData: GuildPluginData<LogsPluginType>,
     pluginData,
     LogType.MEMBER_ROLE_REMOVE,
     createTypedTemplateSafeValueContainer({
-      mod: userToTemplateSafeUser(data.mod),
+      mod: data.mod ? userToTemplateSafeUser(data.mod) : null,
       member: memberToTemplateSafeMember(data.member),
       roles: data.roles.map(r => r.name).join(", "),
     }),
diff --git a/backend/src/plugins/Logs/logFunctions/logMemberTimedUnmute.ts b/backend/src/plugins/Logs/logFunctions/logMemberTimedUnmute.ts
index be850eb8..72ccea64 100644
--- a/backend/src/plugins/Logs/logFunctions/logMemberTimedUnmute.ts
+++ b/backend/src/plugins/Logs/logFunctions/logMemberTimedUnmute.ts
@@ -5,10 +5,11 @@ import { log } from "../util/log";
 import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
 import { User } from "discord.js";
 import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
+import { UnknownUser } from "../../../utils";
 
 interface LogMemberTimedUnmuteData {
   mod: User;
-  user: User;
+  user: User | UnknownUser;
   time: string;
   caseNumber: number;
   reason: string;
@@ -25,6 +26,9 @@ export function logMemberTimedUnmute(pluginData: GuildPluginData<LogsPluginType>
       caseNumber: data.caseNumber,
       reason: data.reason,
     }),
-    {},
+    {
+      userId: data.user.id,
+      bot: data.user instanceof User ? data.user.bot : false,
+    },
   );
 }
diff --git a/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts b/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts
index a3b9b942..ef2aca40 100644
--- a/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts
+++ b/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts
@@ -5,10 +5,11 @@ import { log } from "../util/log";
 import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
 import { GuildMember, User } from "discord.js";
 import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
+import { UnknownUser } from "../../../utils";
 
 interface LogMemberUnmuteData {
-  mod: GuildMember;
-  user: User;
+  mod: User;
+  user: User | UnknownUser;
   caseNumber: number;
   reason: string;
 }
@@ -18,14 +19,14 @@ export function logMemberUnmute(pluginData: GuildPluginData<LogsPluginType>, dat
     pluginData,
     LogType.MEMBER_UNMUTE,
     createTypedTemplateSafeValueContainer({
-      mod: memberToTemplateSafeMember(data.mod),
+      mod: userToTemplateSafeUser(data.mod),
       user: userToTemplateSafeUser(data.user),
       caseNumber: data.caseNumber,
       reason: data.reason,
     }),
     {
       userId: data.user.id,
-      bot: data.user.bot,
+      bot: data.user instanceof User ? data.user.bot : false,
     },
   );
 }
diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts b/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts
index ad8b9b72..4ce4694c 100644
--- a/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts
+++ b/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts
@@ -31,7 +31,7 @@ export function logMessageDeleteAuto(pluginData: GuildPluginData<LogsPluginType>
     }),
     {
       userId: data.user.id,
-      bot: data.user.bot,
+      bot: data.user instanceof User ? data.user.bot : false,
       channel: data.channel.id,
       category: data.channel.parentId,
     },
diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts
index 34512a14..40a352c7 100644
--- a/backend/src/plugins/ModActions/commands/BanCmd.ts
+++ b/backend/src/plugins/ModActions/commands/BanCmd.ts
@@ -119,7 +119,7 @@ export const BanCmd = modActionsCmd({
             });
           } else {
             pluginData.getPlugin(LogsPlugin).logMemberBan({
-              mod,
+              mod: mod.user,
               user,
               caseNumber: createdCase.case_number,
               reason,
diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts
index 04ee3d59..73a07b80 100644
--- a/backend/src/plugins/Mutes/functions/unmuteUser.ts
+++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts
@@ -93,14 +93,14 @@ export async function unmuteUser(
       user,
       caseNumber: createdCase.case_number,
       time: timeUntilUnmute,
-      reason: caseArgs.reason,
+      reason: caseArgs.reason ?? "",
     });
   } else {
     pluginData.getPlugin(LogsPlugin).logMemberUnmute({
       mod,
       user,
       caseNumber: createdCase.case_number,
-      reason: caseArgs.reason,
+      reason: caseArgs.reason ?? "",
     });
   }
 
diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts
index 388f03a1..e5e25d70 100644
--- a/backend/src/plugins/Post/util/actualPostCmd.ts
+++ b/backend/src/plugins/Post/util/actualPostCmd.ts
@@ -192,7 +192,7 @@ export async function actualPostCmd(
       date: postAt.format(timeAndDate.getDateFormat("date")),
       time: postAt.format(timeAndDate.getDateFormat("time")),
       repeatInterval: humanizeDuration(opts.repeat),
-      repeatDetails: repeatDetailsStr,
+      repeatDetails: repeatDetailsStr ?? "",
     });
   }
 
diff --git a/backend/src/plugins/Post/util/scheduledPostLoop.ts b/backend/src/plugins/Post/util/scheduledPostLoop.ts
index 1c992311..2a946c1e 100644
--- a/backend/src/plugins/Post/util/scheduledPostLoop.ts
+++ b/backend/src/plugins/Post/util/scheduledPostLoop.ts
@@ -4,7 +4,7 @@ import moment from "moment-timezone";
 import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
 import { LogType } from "../../../data/LogType";
 import { logger } from "../../../logger";
-import { DBDateFormat, SECONDS } from "../../../utils";
+import { DBDateFormat, SECONDS, verboseChannelMention, verboseUserMention } from "../../../utils";
 import { PostPluginType } from "../types";
 import { postMessage } from "./postMessage";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
@@ -38,9 +38,9 @@ export async function scheduledPostLoop(pluginData: GuildPluginData<PostPluginTy
         });
       } catch {
         pluginData.getPlugin(LogsPlugin).logBotAlert({
-          body: `Failed to post scheduled message by {userMention(author)} to {channelMention(channel)}`,
-          channel,
-          author,
+          body: `Failed to post scheduled message by ${verboseUserMention(author)} to ${verboseChannelMention(
+            channel,
+          )}`,
         });
         logger.warn(
           `Failed to post scheduled message to #${channel.name} (${channel.id}) on ${pluginData.guild.name} (${pluginData.guild.id})`,
diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts
index 3d7fb3d5..65ace443 100644
--- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts
+++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts
@@ -49,24 +49,18 @@ export const ButtonInteractionEvt = reactionRolesEvt({
     const group = cfg.button_groups[context.groupName];
     if (!group) {
       await sendEphemeralReply(int, `A configuration error was encountered, please contact the Administrators!`);
-      meta.pluginData
-        .getPlugin(LogsPlugin)
-        .log(
-          LogType.BOT_ALERT,
-          `**A configuration error occurred** on buttons for message ${int.message.id}, group **${context.groupName}** not found in config`,
-        );
+      meta.pluginData.getPlugin(LogsPlugin).logBotAlert({
+        body: `**A configuration error occurred** on buttons for message ${int.message.id}, group **${context.groupName}** not found in config`,
+      });
       return;
     }
 
     // Verify that detected action is known by us
     if (!(<any>Object).values(ButtonMenuActions).includes(context.action)) {
       await sendEphemeralReply(int, `A internal error was encountered, please contact the Administrators!`);
-      meta.pluginData
-        .getPlugin(LogsPlugin)
-        .log(
-          LogType.BOT_ALERT,
-          `**A internal error occurred** on buttons for message ${int.message.id}, action **${context.action}** is not known`,
-        );
+      meta.pluginData.getPlugin(LogsPlugin).logBotAlert({
+        body: `**A internal error occurred** on buttons for message ${int.message.id}, action **${context.action}** is not known`,
+      });
       return;
     }
 
diff --git a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts
index 446cc0ee..8c9884a9 100644
--- a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts
+++ b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts
@@ -18,12 +18,9 @@ export async function handleOpenMenu(
       content: `A configuration error was encountered, please contact the Administrators!`,
       ephemeral: true,
     });
-    pluginData
-      .getPlugin(LogsPlugin)
-      .log(
-        LogType.BOT_ALERT,
-        `**A configuration error occurred** on buttons for message ${int.message.id}, no menus found in config`,
-      );
+    pluginData.getPlugin(LogsPlugin).logBotAlert({
+      body: `**A configuration error occurred** on buttons for message ${int.message.id}, no menus found in config`,
+    });
     return;
   }
 
@@ -48,12 +45,9 @@ export async function handleOpenMenu(
       content: `A configuration error was encountered, please contact the Administrators!`,
       ephemeral: true,
     });
-    pluginData
-      .getPlugin(LogsPlugin)
-      .log(
-        LogType.BOT_ALERT,
-        `**A configuration error occurred** on buttons for message ${int.message.id}, menu **${context.roleOrMenu}** not found in config`,
-      );
+    pluginData.getPlugin(LogsPlugin).logBotAlert({
+      body: `**A configuration error occurred** on buttons for message ${int.message.id}, menu **${context.roleOrMenu}** not found in config`,
+    });
     return;
   }
   const rows = splitButtonsIntoRows(menuButtons, Object.values(group.button_menus[context.roleOrMenu])); // new MessageActionRow().addComponents(menuButtons);
@@ -73,12 +67,9 @@ export async function handleModifyRole(
       content: `A configuration error was encountered, please contact the Administrators!`,
       ephemeral: true,
     });
-    pluginData
-      .getPlugin(LogsPlugin)
-      .log(
-        LogType.BOT_ALERT,
-        `**A configuration error occurred** on buttons for message ${int.message.id}, role **${context.roleOrMenu}** not found on server`,
-      );
+    pluginData.getPlugin(LogsPlugin).logBotAlert({
+      body: `**A configuration error occurred** on buttons for message ${int.message.id}, role **${context.roleOrMenu}** not found on server`,
+    });
     return;
   }
 
@@ -96,11 +87,8 @@ export async function handleModifyRole(
       content: "A configuration error was encountered, please contact the Administrators!",
       ephemeral: true,
     });
-    pluginData
-      .getPlugin(LogsPlugin)
-      .log(
-        LogType.BOT_ALERT,
-        `**A configuration error occurred** on buttons for message ${int.message.id}, error: ${e}. We might be missing permissions!`,
-      );
+    pluginData.getPlugin(LogsPlugin).logBotAlert({
+      body: `**A configuration error occurred** on buttons for message ${int.message.id}, error: ${e}. We might be missing permissions!`,
+    });
   }
 }
diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts
index 564b9f77..23229ca5 100644
--- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts
+++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts
@@ -54,10 +54,10 @@ export const AddRoleCmd = rolesCmd({
 
     await args.member.roles.add(roleId);
 
-    pluginData.getPlugin(LogsPlugin).logMemberRoleAdd(LogType.MEMBER_ROLE_ADD, {
-      member: memberToTemplateSafeMember(args.member),
-      roles: role.name,
-      mod: userToTemplateSafeUser(msg.author),
+    pluginData.getPlugin(LogsPlugin).logMemberRoleAdd({
+      mod: msg.author,
+      member: args.member,
+      roles: [role],
     });
 
     sendSuccessMessage(
diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts
index e7a834a7..0f852e14 100644
--- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts
+++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts
@@ -69,7 +69,7 @@ export const VcmoveCmd = utilityCmd({
       return;
     }
 
-    const oldVoiceChannel = pluginData.guild.channels.cache.get(args.member.voice.channelId);
+    const oldVoiceChannel = pluginData.guild.channels.cache.get(args.member.voice.channelId) as VoiceChannel;
 
     try {
       await args.member.edit({
@@ -83,7 +83,7 @@ export const VcmoveCmd = utilityCmd({
     pluginData.getPlugin(LogsPlugin).logVoiceChannelForceMove({
       mod: msg.author,
       member: args.member,
-      oldChannel: oldVoiceChannel!,
+      oldChannel: oldVoiceChannel,
       newChannel: channel,
     });
 
diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts
index 11afa607..bf124fa0 100644
--- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts
+++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts
@@ -6,7 +6,7 @@ import {
 } from "../../../utils/templateSafeObjects";
 import { LogType } from "../../../data/LogType";
 import { renderTemplate, TemplateParseError } from "../../../templateFormatter";
-import { createChunkedMessage, stripObjectToScalars } from "../../../utils";
+import { createChunkedMessage, stripObjectToScalars, verboseChannelMention, verboseUserMention } from "../../../utils";
 import { sendDM } from "../../../utils/sendDM";
 import { welcomeMessageEvt } from "../types";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
@@ -68,9 +68,9 @@ export const SendWelcomeMessageEvt = welcomeMessageEvt({
         await createChunkedMessage(channel, formatted);
       } catch {
         pluginData.getPlugin(LogsPlugin).logBotAlert({
-          body: `Failed send a welcome message for {userMention(member)} to {channelMention(channel)}`,
-          member,
-          channel,
+          body: `Failed send a welcome message for ${verboseUserMention(member.user)} to ${verboseChannelMention(
+            channel,
+          )}`,
         });
       }
     }