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 <noreply@anthropic.com>
This commit is contained in:
Rosie Val 2026-07-28 23:34:04 +01:00
parent 940c15c27d
commit 6dfefbe6dc
3 changed files with 0 additions and 24 deletions

View file

@ -257,8 +257,6 @@ class Affiliates(commands.Cog):
@commands.admin_or_permissions(administrator=True) @commands.admin_or_permissions(administrator=True)
async def poj(self, ctx: commands.Context): async def poj(self, ctx: commands.Context):
"""👋 POJ — Ping on Join: mention new members, then auto-delete the ping.""" """👋 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"]) @poj.command(name="enable", aliases=["on"])
async def poj_enable(self, ctx: commands.Context): async def poj_enable(self, ctx: commands.Context):
@ -275,8 +273,6 @@ class Affiliates(commands.Cog):
@poj.group(name="channel") @poj.group(name="channel")
async def poj_channel(self, ctx: commands.Context): async def poj_channel(self, ctx: commands.Context):
"""Manage which channels ping new members on join.""" """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") @poj_channel.command(name="add")
async def poj_channel_add( async def poj_channel_add(
@ -345,8 +341,6 @@ class Affiliates(commands.Cog):
@commands.guild_only() @commands.guild_only()
async def aff(self, ctx: commands.Context): async def aff(self, ctx: commands.Context):
"""🤝 Affiliates — the affiliate-server board and DM affiliates.""" """🤝 Affiliates — the affiliate-server board and DM affiliates."""
if ctx.invoked_subcommand is None:
await ctx.send_help(ctx.command)
@aff.command(name="channel") @aff.command(name="channel")
@commands.admin_or_permissions(administrator=True) @commands.admin_or_permissions(administrator=True)
@ -426,8 +420,6 @@ class Affiliates(commands.Cog):
@aff.group(name="dm") @aff.group(name="dm")
async def aff_dm(self, ctx: commands.Context): async def aff_dm(self, ctx: commands.Context):
"""Manage the separate DM-affiliates list, sent to new members on join.""" """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") @aff_dm.command(name="add")
@commands.admin_or_permissions(administrator=True) @commands.admin_or_permissions(administrator=True)

View file

@ -644,8 +644,6 @@ class GhostWipe(commands.Cog):
@commands.admin_or_permissions(administrator=True) @commands.admin_or_permissions(administrator=True)
async def ghostwipe(self, ctx: commands.Context): async def ghostwipe(self, ctx: commands.Context):
"""👻 GhostWipe — auto-delete a departing member's messages, with a full HTML audit log.""" """👻 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"]) @ghostwipe.command(name="enable", aliases=["on"])
async def gw_enable(self, ctx: commands.Context): async def gw_enable(self, ctx: commands.Context):
@ -699,8 +697,6 @@ class GhostWipe(commands.Cog):
@ghostwipe.group(name="whitelist") @ghostwipe.group(name="whitelist")
async def gw_whitelist(self, ctx: commands.Context): async def gw_whitelist(self, ctx: commands.Context):
"""Manage users who are never purged, no matter how they leave.""" """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") @gw_whitelist.command(name="add")
async def gw_whitelist_add(self, ctx: commands.Context, user: discord.User): async def gw_whitelist_add(self, ctx: commands.Context, user: discord.User):
@ -726,8 +722,6 @@ class GhostWipe(commands.Cog):
@ghostwipe.group(name="ignorerole") @ghostwipe.group(name="ignorerole")
async def gw_ignorerole(self, ctx: commands.Context): async def gw_ignorerole(self, ctx: commands.Context):
"""Manage roles that exempt a member from being purged.""" """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") @gw_ignorerole.command(name="add")
async def gw_ignorerole_add(self, ctx: commands.Context, role: discord.Role): async def gw_ignorerole_add(self, ctx: commands.Context, role: discord.Role):
@ -755,8 +749,6 @@ class GhostWipe(commands.Cog):
@ghostwipe.group(name="ignorechannel") @ghostwipe.group(name="ignorechannel")
async def gw_ignorechannel(self, ctx: commands.Context): async def gw_ignorechannel(self, ctx: commands.Context):
"""Manage channels/threads GhostWipe never scans.""" """Manage channels/threads GhostWipe never scans."""
if ctx.invoked_subcommand is None:
await ctx.send_help(ctx.command)
@gw_ignorechannel.command(name="add") @gw_ignorechannel.command(name="add")
async def gw_ignorechannel_add( async def gw_ignorechannel_add(
@ -835,8 +827,6 @@ class GhostWipe(commands.Cog):
@ghostwipe.group(name="report") @ghostwipe.group(name="report")
async def gw_report(self, ctx: commands.Context): async def gw_report(self, ctx: commands.Context):
"""Configure the HTML report output.""" """Configure the HTML report output."""
if ctx.invoked_subcommand is None:
await ctx.send_help(ctx.command)
@gw_report.command(name="content") @gw_report.command(name="content")
async def gw_report_content(self, ctx: commands.Context, toggle: bool): async def gw_report_content(self, ctx: commands.Context, toggle: bool):

View file

@ -253,8 +253,6 @@ class ImageVault(commands.Cog):
Configuration and `list` are staff-only; `show`/`get`, `mine`, and `stats` Configuration and `list` are staff-only; `show`/`get`, `mine`, and `stats`
are open to whoever the `retrieve` permission mode allows. 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"]) @imagevault.command(name="enable", aliases=["on"])
@commands.admin_or_permissions(administrator=True) @commands.admin_or_permissions(administrator=True)
@ -306,8 +304,6 @@ class ImageVault(commands.Cog):
@commands.admin_or_permissions(administrator=True) @commands.admin_or_permissions(administrator=True)
async def iv_watchchannel(self, ctx: commands.Context): async def iv_watchchannel(self, ctx: commands.Context):
"""Manage the channel watch-list. Empty list = watch every channel.""" """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") @iv_watchchannel.command(name="add")
async def iv_watchchannel_add( async def iv_watchchannel_add(
@ -340,8 +336,6 @@ class ImageVault(commands.Cog):
@commands.admin_or_permissions(administrator=True) @commands.admin_or_permissions(administrator=True)
async def iv_ignorechannel(self, ctx: commands.Context): async def iv_ignorechannel(self, ctx: commands.Context):
"""Manage channels ImageVault never touches (only applies when the watch-list is empty).""" """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") @iv_ignorechannel.command(name="add")
async def iv_ignorechannel_add( async def iv_ignorechannel_add(