From 6dfefbe6dcd666568638faaff8c3e46fc7c58258 Mon Sep 17 00:00:00 2001 From: Rosie Val Date: Tue, 28 Jul 2026 23:34:04 +0100 Subject: [PATCH] Remove redundant manual send_help from command groups redbot.core.commands.Group has autohelp=True by default, and its invoke() override already calls ctx.send_help() unconditionally whenever no subcommand matches. Manually calling it too (the `if ctx.invoked_subcommand is None: await ctx.send_help(ctx.command)` pattern) caused help to be sent twice on every bare group invocation across GhostWipe, ImageVault, and Affiliates. Verified against Red's actual Group.invoke() source before fixing. Co-Authored-By: Claude Sonnet 5 --- affiliates/affiliates.py | 8 -------- ghostwipe/ghostwipe.py | 10 ---------- imagevault/imagevault.py | 6 ------ 3 files changed, 24 deletions(-) diff --git a/affiliates/affiliates.py b/affiliates/affiliates.py index 8d7cbc4..b414078 100644 --- a/affiliates/affiliates.py +++ b/affiliates/affiliates.py @@ -257,8 +257,6 @@ class Affiliates(commands.Cog): @commands.admin_or_permissions(administrator=True) async def poj(self, ctx: commands.Context): """👋 POJ — Ping on Join: mention new members, then auto-delete the ping.""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @poj.command(name="enable", aliases=["on"]) async def poj_enable(self, ctx: commands.Context): @@ -275,8 +273,6 @@ class Affiliates(commands.Cog): @poj.group(name="channel") async def poj_channel(self, ctx: commands.Context): """Manage which channels ping new members on join.""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @poj_channel.command(name="add") async def poj_channel_add( @@ -345,8 +341,6 @@ class Affiliates(commands.Cog): @commands.guild_only() async def aff(self, ctx: commands.Context): """🤝 Affiliates — the affiliate-server board and DM affiliates.""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @aff.command(name="channel") @commands.admin_or_permissions(administrator=True) @@ -426,8 +420,6 @@ class Affiliates(commands.Cog): @aff.group(name="dm") async def aff_dm(self, ctx: commands.Context): """Manage the separate DM-affiliates list, sent to new members on join.""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @aff_dm.command(name="add") @commands.admin_or_permissions(administrator=True) diff --git a/ghostwipe/ghostwipe.py b/ghostwipe/ghostwipe.py index 0e63cf5..0abd65e 100644 --- a/ghostwipe/ghostwipe.py +++ b/ghostwipe/ghostwipe.py @@ -644,8 +644,6 @@ class GhostWipe(commands.Cog): @commands.admin_or_permissions(administrator=True) async def ghostwipe(self, ctx: commands.Context): """👻 GhostWipe — auto-delete a departing member's messages, with a full HTML audit log.""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @ghostwipe.command(name="enable", aliases=["on"]) async def gw_enable(self, ctx: commands.Context): @@ -699,8 +697,6 @@ class GhostWipe(commands.Cog): @ghostwipe.group(name="whitelist") async def gw_whitelist(self, ctx: commands.Context): """Manage users who are never purged, no matter how they leave.""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @gw_whitelist.command(name="add") async def gw_whitelist_add(self, ctx: commands.Context, user: discord.User): @@ -726,8 +722,6 @@ class GhostWipe(commands.Cog): @ghostwipe.group(name="ignorerole") async def gw_ignorerole(self, ctx: commands.Context): """Manage roles that exempt a member from being purged.""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @gw_ignorerole.command(name="add") async def gw_ignorerole_add(self, ctx: commands.Context, role: discord.Role): @@ -755,8 +749,6 @@ class GhostWipe(commands.Cog): @ghostwipe.group(name="ignorechannel") async def gw_ignorechannel(self, ctx: commands.Context): """Manage channels/threads GhostWipe never scans.""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @gw_ignorechannel.command(name="add") async def gw_ignorechannel_add( @@ -835,8 +827,6 @@ class GhostWipe(commands.Cog): @ghostwipe.group(name="report") async def gw_report(self, ctx: commands.Context): """Configure the HTML report output.""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @gw_report.command(name="content") async def gw_report_content(self, ctx: commands.Context, toggle: bool): diff --git a/imagevault/imagevault.py b/imagevault/imagevault.py index 35daa99..d972fa4 100644 --- a/imagevault/imagevault.py +++ b/imagevault/imagevault.py @@ -253,8 +253,6 @@ class ImageVault(commands.Cog): Configuration and `list` are staff-only; `show`/`get`, `mine`, and `stats` are open to whoever the `retrieve` permission mode allows. """ - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @imagevault.command(name="enable", aliases=["on"]) @commands.admin_or_permissions(administrator=True) @@ -306,8 +304,6 @@ class ImageVault(commands.Cog): @commands.admin_or_permissions(administrator=True) async def iv_watchchannel(self, ctx: commands.Context): """Manage the channel watch-list. Empty list = watch every channel.""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @iv_watchchannel.command(name="add") async def iv_watchchannel_add( @@ -340,8 +336,6 @@ class ImageVault(commands.Cog): @commands.admin_or_permissions(administrator=True) async def iv_ignorechannel(self, ctx: commands.Context): """Manage channels ImageVault never touches (only applies when the watch-list is empty).""" - if ctx.invoked_subcommand is None: - await ctx.send_help(ctx.command) @iv_ignorechannel.command(name="add") async def iv_ignorechannel_add(