# Buggy code
async def genre(self, ctx: commands.Context):
    """Pick a Spotify playlist from a list of categories to start playing."""

    async def _category_search_menu(
        ctx: commands.Context,
        pages: list,
        controls: dict,
        message: discord.Message,
        page: int,
        timeout: float,
        emoji: str,
    ):
        if message:
            output = await self._genre_search_button_action(
                ctx, category_list, emoji, page
            )
            with contextlib.suppress(discord.HTTPException):
                await message.delete()
            return output

    async def _playlist_search_menu(
        ctx: commands.Context,
        pages: list,
        controls: dict,
        message: discord.Message,
        page: int,
        timeout: float,
        emoji: str,
    ):
        if message:
            output = await self._genre_search_button_action(
                ctx, playlists_list, emoji, page, playlist=True
            )
            with contextlib.suppress(discord.HTTPException):
                await message.delete()
            return output

    category_search_controls = {
        "1⃣": _category_search_menu,
        "2⃣": _category_search_menu,
        "3⃣": _category_search_menu,
        "4⃣": _category_search_menu,
        "5⃣": _category_search_menu,
        "⬅": prev_page,
        "❌": close_menu,
        "➡": next_page,
    }
    playlist_search_controls = {
        "1⃣": _playlist_search_menu,
        "2⃣": _playlist_search_menu,
        "3⃣": _playlist_search_menu,
        "4⃣": _playlist_search_menu,
        "5⃣": _playlist_search_menu,
        "⬅": prev_page,
        "❌": close_menu,
        "➡": next_page,
    }

    api_data = await self._check_api_tokens()
    if any(
        [
            not api_data["spotify_client_id"],
            not api_data["spotify_client_secret"],
            not api_data["youtube_api"],
        ]
    ):
        return await self._embed_msg(
            ctx,
            _(
                "The owner needs to set the Spotify client ID, Spotify client secret, "
                "and YouTube API key before Spotify URLs or codes can be used. "
                "\nSee `{prefix}audioset youtubeapi` and `{prefix}audioset spotifyapi` "
                "for instructions."
            ).format(prefix=ctx.prefix),
        )
    guild_data = await self.config.guild(ctx.guild).all()
    if not self._player_check(ctx):
        if self._connection_aborted:
            msg = _("Connection to Lavalink has failed.")
            if await ctx.bot.is_owner(ctx.author):
                msg += " " + _("Please check your console or logs for details.")
            return await self._embed_msg(ctx, msg)
        try:
            if (
                not ctx.author.voice.channel.permissions_for(ctx.me).connect
                or not ctx.author.voice.channel.permissions_for(ctx.me).move_members
                and userlimit(ctx.author.voice.channel)
            ):
                return await self._embed_msg(
                    ctx, _("I don't have permission to connect to your channel.")
                )
            await lavalink.connect(ctx.author.voice.channel)
            player = lavalink.get_player(ctx.guild.id)
            player.store("connect", datetime.datetime.utcnow())
        except AttributeError:
            return await self._embed_msg(ctx, _("Connect to a voice channel first."))
        except IndexError:
            return await self._embed_msg(
                ctx, _("Connection to Lavalink has not yet been established.")
            )
    if guild_data["dj_enabled"]:
        if not await self._can_instaskip(ctx, ctx.author):
            return await self._embed_msg(
                ctx, _("You need the DJ role to queue tracks.")
            )
    player = lavalink.get_player(ctx.guild.id)

    player.store("channel", ctx.channel.id)
    player.store("guild", ctx.guild.id)
    await self._eq_check(ctx, player)
    await self._data_check(ctx)
    if (
        not ctx.author.voice or ctx.author.voice.channel != player.channel
    ) and not await self._can_instaskip(ctx, ctx.author):
        return await self._embed_msg(
            ctx, _("You must be in the voice channel to use the genre command.")
        )
    try:
        category_list = await self.music_cache.spotify_api.get_categories()
    except SpotifyFetchError as error:
        return await self._embed_msg(ctx, _(error.message).format(prefix=ctx.prefix))
    if not category_list:
        return await self._embed_msg(ctx, _("No categories found, try again later."))
    len_folder_pages = math.ceil(len(category_list) / 5)
    category_search_page_list = []
    for page_num in range(1, len_folder_pages + 1):
        embed = await self._build_genre_search_page(
            ctx, category_list, page_num, _("Categories")
        )
        category_search_page_list.append(embed)
    cat_menu_output = await menu(
        ctx, category_search_page_list, category_search_controls
    )
    if not cat_menu_output:
        return await self._embed_msg(ctx, _("No categories selected, try again later."))
    category_name, category_pick = cat_menu_output
    playlists_list = await self.music_cache.spotify_api.get_playlist_from_category(
        category_pick
    )
    if not playlists_list:
        return await self._embed_msg(ctx, _("No categories found, try again later."))
    len_folder_pages = math.ceil(len(playlists_list) / 5)
    playlists_search_page_list = []
    for page_num in range(1, len_folder_pages + 1):
        embed = await self._build_genre_search_page(
            ctx,
            playlists_list,
            page_num,
            _("Playlists for {friendly_name}").format(friendly_name=category_name),
            playlist=True,
        )
        playlists_search_page_list.append(embed)
    playlists_pick = await menu(
        ctx, playlists_search_page_list, playlist_search_controls
    )
    query = audio_dataclasses.Query.process_input(playlists_pick)
    if not query.valid:
        return await self._embed_msg(ctx, _("No tracks to play."))
    if not await self._currency_check(ctx, guild_data["jukebox_price"]):
        return
    if query.is_spotify:
        return await self._get_spotify_tracks(ctx, query)
    return await self._embed_msg(
        ctx, _("Couldn't find tracks for the selected playlist.")
    )


# Traceback (RuntimeError)
Traceback (most recent call last):
File "/home/martinebots/martinebotsvenv/lib/python3.7/site-packages/discord/ext/commands/core.py", line 79, in wrapped
ret = await coro(*args, **kwargs)
File "/home/martinebots/martinebotscogs/cogs_modified/audio/audio.py", line 3183, in play
await self._enqueue_tracks(ctx, query)
File "/home/martinebots/martinebotscogs/cogs_modified/audio/audio.py", line 3885, in _enqueue_tracks
result, called_api = await self.music_cache.lavalink_query(ctx, player, query)
File "/home/martinebots/martinebotscogs/cogs_modified/audio/apis.py", line 911, in lavalink_query
results = await player.load_tracks(query)
File "/home/martinebots/martinebotsvenv/lib/python3.7/site-packages/lavalink/rest_api.py", line 300, in load_tracks
self.__check_node_ready()
File "/home/martinebots/martinebotsvenv/lib/python3.7/site-packages/lavalink/rest_api.py", line 268, in __check_node_ready
raise RuntimeError("Cannot execute REST request when node not ready.")
RuntimeError: Cannot execute REST request when node not ready.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/home/martinebots/martinebotsvenv/lib/python3.7/site-packages/discord/ext/commands/bot.py", line 863, in invoke
await ctx.command.invoke(ctx)
File "/home/martinebots/martinebotsvenv/lib/python3.7/site-packages/discord/ext/commands/core.py", line 728, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/home/martinebots/martinebotsvenv/lib/python3.7/site-packages/discord/ext/commands/core.py", line 88, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: RuntimeError: Cannot execute REST request when node not ready.```

# Fixed code
async def genre(self, ctx: commands.Context):
    """Pick a Spotify playlist from a list of categories to start playing."""

    async def _category_search_menu(
        ctx: commands.Context,
        pages: list,
        controls: MutableMapping,
        message: discord.Message,
        page: int,
        timeout: float,
        emoji: str,
    ):
        if message:
            output = await self._genre_search_button_action(
                ctx, category_list, emoji, page
            )
            with contextlib.suppress(discord.HTTPException):
                await message.delete()
            return output

    async def _playlist_search_menu(
        ctx: commands.Context,
        pages: list,
        controls: MutableMapping,
        message: discord.Message,
        page: int,
        timeout: float,
        emoji: str,
    ):
        if message:
            output = await self._genre_search_button_action(
                ctx, playlists_list, emoji, page, playlist=True
            )
            with contextlib.suppress(discord.HTTPException):
                await message.delete()
            return output

    category_search_controls = {
        "\N{DIGIT ONE}\N{COMBINING ENCLOSING KEYCAP}": _category_search_menu,
        "\N{DIGIT TWO}\N{COMBINING ENCLOSING KEYCAP}": _category_search_menu,
        "\N{DIGIT THREE}\N{COMBINING ENCLOSING KEYCAP}": _category_search_menu,
        "\N{DIGIT FOUR}\N{COMBINING ENCLOSING KEYCAP}": _category_search_menu,
        "\N{DIGIT FIVE}\N{COMBINING ENCLOSING KEYCAP}": _category_search_menu,
        "\N{LEFTWARDS BLACK ARROW}": prev_page,
        "\N{CROSS MARK}": close_menu,
        "\N{BLACK RIGHTWARDS ARROW}": next_page,
    }
    playlist_search_controls = {
        "\N{DIGIT ONE}\N{COMBINING ENCLOSING KEYCAP}": _playlist_search_menu,
        "\N{DIGIT TWO}\N{COMBINING ENCLOSING KEYCAP}": _playlist_search_menu,
        "\N{DIGIT THREE}\N{COMBINING ENCLOSING KEYCAP}": _playlist_search_menu,
        "\N{DIGIT FOUR}\N{COMBINING ENCLOSING KEYCAP}": _playlist_search_menu,
        "\N{DIGIT FIVE}\N{COMBINING ENCLOSING KEYCAP}": _playlist_search_menu,
        "\N{LEFTWARDS BLACK ARROW}": prev_page,
        "\N{CROSS MARK}": close_menu,
        "\N{BLACK RIGHTWARDS ARROW}": next_page,
    }

    api_data = await self._check_api_tokens()
    if any(
        [
            not api_data["spotify_client_id"],
            not api_data["spotify_client_secret"],
            not api_data["youtube_api"],
        ]
    ):
        return await self._embed_msg(
            ctx,
            title=_("Invalid Environment"),
            description=_(
                "The owner needs to set the Spotify client ID, Spotify client secret, "
                "and YouTube API key before Spotify URLs or codes can be used. "
                "\nSee `{prefix}audioset youtubeapi` and `{prefix}audioset spotifyapi` "
                "for instructions."
            ).format(prefix=ctx.prefix),
        )
    guild_data = await self.config.guild(ctx.guild).all()
    if not self._player_check(ctx):
        if self._connection_aborted:
            msg = _("Connection to Lavalink has failed")
            desc = EmptyEmbed
            if await ctx.bot.is_owner(ctx.author):
                desc = _("Please check your console or logs for details.")
            return await self._embed_msg(ctx, title=msg, description=desc)
        try:
            if (
                not ctx.author.voice.channel.permissions_for(ctx.me).connect
                or not ctx.author.voice.channel.permissions_for(ctx.me).move_members
                and userlimit(ctx.author.voice.channel)
            ):
                return await self._embed_msg(
                    ctx,
                    title=_("Unable To Play Tracks"),
                    description=_(
                        "I don't have permission to connect to your channel."
                    ),
                )
            await lavalink.connect(ctx.author.voice.channel)
            player = lavalink.get_player(ctx.guild.id)
            player.store("connect", datetime.datetime.utcnow())
        except AttributeError:
            return await self._embed_msg(
                ctx,
                title=_("Unable To Play Tracks"),
                description=_("Connect to a voice channel first."),
            )
        except IndexError:
            return await self._embed_msg(
                ctx,
                title=_("Unable To Play Tracks"),
                description=_("Connection to Lavalink has not yet been established."),
            )
    if guild_data["dj_enabled"]:
        if not await self._can_instaskip(ctx, ctx.author):
            return await self._embed_msg(
                ctx,
                title=_("Unable To Play Tracks"),
                description=_("You need the DJ role to queue tracks."),
            )
    player = lavalink.get_player(ctx.guild.id)

    player.store("channel", ctx.channel.id)
    player.store("guild", ctx.guild.id)
    await self._eq_check(ctx, player)
    await self._data_check(ctx)
    if (
        not ctx.author.voice or ctx.author.voice.channel != player.channel
    ) and not await self._can_instaskip(ctx, ctx.author):
        return await self._embed_msg(
            ctx,
            title=_("Unable To Play Tracks"),
            description=_("You must be in the voice channel to use the genre command."),
        )
    try:
        category_list = await self.music_cache.spotify_api.get_categories()
    except SpotifyFetchError as error:
        return await self._embed_msg(
            ctx,
            title=_("No categories found"),
            description=_(error.message).format(prefix=ctx.prefix),
        )
    if not category_list:
        return await self._embed_msg(
            ctx, title=_("No categories found, try again later.")
        )
    len_folder_pages = math.ceil(len(category_list) / 5)
    category_search_page_list = []
    for page_num in range(1, len_folder_pages + 1):
        embed = await self._build_genre_search_page(
            ctx, category_list, page_num, _("Categories")
        )
        category_search_page_list.append(embed)
    cat_menu_output = await menu(
        ctx, category_search_page_list, category_search_controls
    )
    if not cat_menu_output:
        return await self._embed_msg(
            ctx, title=_("No categories selected, try again later.")
        )
    category_name, category_pick = cat_menu_output
    playlists_list = await self.music_cache.spotify_api.get_playlist_from_category(
        category_pick
    )
    if not playlists_list:
        return await self._embed_msg(
            ctx, title=_("No categories found, try again later.")
        )
    len_folder_pages = math.ceil(len(playlists_list) / 5)
    playlists_search_page_list = []
    for page_num in range(1, len_folder_pages + 1):
        embed = await self._build_genre_search_page(
            ctx,
            playlists_list,
            page_num,
            _("Playlists for {friendly_name}").format(friendly_name=category_name),
            playlist=True,
        )
        playlists_search_page_list.append(embed)
    playlists_pick = await menu(
        ctx, playlists_search_page_list, playlist_search_controls
    )
    query = audio_dataclasses.Query.process_input(playlists_pick)
    if not query.valid:
        return await self._embed_msg(ctx, title=_("No tracks to play."))
    if not await self._currency_check(ctx, guild_data["jukebox_price"]):
        return
    if query.is_spotify:
        return await self._get_spotify_tracks(ctx, query)
    return await self._embed_msg(
        ctx, title=_("Couldn't find tracks for the selected playlist.")
    )