# Buggy code
async def fuzzy_command_search(ctx: commands.Context, term: str):
    out = []

    if ctx.guild is not None:
        enabled = await ctx.bot.db.guild(ctx.guild).fuzzy()
    else:
        enabled = await ctx.bot.db.fuzzy()

    if not enabled:
        return None

    alias_cog = ctx.bot.get_cog("Alias")
    if alias_cog is not None:
        is_alias, alias = await alias_cog.is_alias(ctx.guild, term)

        if is_alias:
            return None

    customcom_cog = ctx.bot.get_cog("CustomCommands")
    if customcom_cog is not None:
        cmd_obj = customcom_cog.commandobj

        try:
            ccinfo = await cmd_obj.get(ctx.message, term)
        except:
            pass
        else:
            return None

    extracted_cmds = await filter_commands(
        ctx, process.extract(term, ctx.bot.walk_commands(), limit=5)
    )

    if not extracted_cmds:
        return None

    for pos, extracted in enumerate(extracted_cmds, 1):
        short = " - {}".format(extracted[0].short_doc) if extracted[0].short_doc else ""
        out.append(
            "{0}. {1.prefix}{2.qualified_name}{3}".format(pos, ctx, extracted[0], short)
        )

    return box("\n".join(out), lang="Perhaps you wanted one of these?")


# Traceback (AttributeError)
[19/08/2018 19:47] ERROR events on_error 181: Exception in on_command_error
Traceback (most recent call last):
File "/home/tobyh/PycharmProjects/Red-DiscordBot/.venv/src/discord.py/discord/client.py", line 220, in _run_event
await coro(*args, **kwargs)
File "/home/tobyh/PycharmProjects/Red-DiscordBot/redbot/core/events.py", line 234, in on_command_error
fuzzy_result = await fuzzy_command_search(ctx, ctx.invoked_with)
File "/home/tobyh/PycharmProjects/Red-DiscordBot/redbot/core/utils/__init__.py", line 52, in fuzzy_command_search
is_alias, alias = await alias_cog.is_alias(ctx.guild, term)
File "/home/tobyh/PycharmProjects/Red-DiscordBot/redbot/cogs/alias/alias.py", line 60, in is_alias
server_aliases = await self.unloaded_aliases(guild)
File "/home/tobyh/PycharmProjects/Red-DiscordBot/redbot/cogs/alias/alias.py", line 41, in unloaded_aliases
return (AliasEntry.from_json(d) for d in (await self._aliases.guild(guild).entries()))
File "/home/tobyh/PycharmProjects/Red-DiscordBot/redbot/core/config.py", line 761, in guild
return self._get_base_group(self.GUILD, guild.id)
AttributeError: 'NoneType' object has no attribute 'id'

# Fixed code
async def fuzzy_command_search(
    ctx: commands.Context, term: Optional[str] = None, *, min_score: int = 80
) -> Optional[List[commands.Command]]:
    """Search for commands which are similar in name to the one invoked.

    Returns a maximum of 5 commands which must all be at least matched
    greater than ``min_score``.

    Parameters
    ----------
    ctx : `commands.Context <redbot.core.commands.Context>`
        The command invocation context.
    term : Optional[str]
        The name of the invoked command. If ``None``, `Context.invoked_with`
        will be used instead.
    min_score : int
        The minimum score for matched commands to reach. Defaults to 80.

    Returns
    -------
    Optional[List[`commands.Command <redbot.core.commands.Command>`]]
        A list of commands which were fuzzily matched with the invoked
        command.

    """
    if ctx.guild is not None:
        enabled = await ctx.bot.db.guild(ctx.guild).fuzzy()
    else:
        enabled = await ctx.bot.db.fuzzy()

    if not enabled:
        return

    if term is None:
        term = ctx.invoked_with

    # If the term is an alias or CC, we don't want to send a supplementary fuzzy search.
    alias_cog = ctx.bot.get_cog("Alias")
    if alias_cog is not None:
        is_alias, alias = await alias_cog.is_alias(ctx.guild, term)

        if is_alias:
            return
    customcom_cog = ctx.bot.get_cog("CustomCommands")
    if customcom_cog is not None:
        cmd_obj = customcom_cog.commandobj

        try:
            await cmd_obj.get(ctx.message, term)
        except:
            pass
        else:
            return

    # Do the scoring. `extracted` is a list of tuples in the form `(command, score)`
    extracted = process.extract(
        term, ctx.bot.walk_commands(), limit=5, scorer=fuzz.QRatio
    )
    if not extracted:
        return

    # Filter through the fuzzy-matched commands.
    matched_commands = []
    for command, score in extracted:
        if score < min_score:
            # Since the list is in decreasing order of score, we can exit early.
            break
        if await command.can_see(ctx):
            matched_commands.append(command)

    return matched_commands