# Buggy code
def _get_updated_schema(
    old_config: _OldConfigSchema,
) -> Tuple[_NewConfigSchema, _NewConfigSchema]:
    # Prior to 1.0.0, the schema was in this form for both global
    # and guild-based rules:
    # "owner_models"
    # -> "cogs"
    #   -> Cog names...
    #     -> "allow"
    #       -> [Model IDs...]
    #     -> "deny"
    #       -> [Model IDs...]
    #     -> "default"
    #       -> "allow"|"deny"
    # -> "commands"
    #   -> Command names...
    #     -> "allow"
    #       -> [Model IDs...]
    #     -> "deny"
    #       -> [Model IDs...]
    #     -> "default"
    #       -> "allow"|"deny"

    new_cog_rules = {}
    new_cmd_rules = {}
    for guild_id, old_rules in old_config.items():
        if "owner_models" not in old_rules:
            continue
        old_rules = old_rules["owner_models"]
        for category, new_rules in zip(
            ("cogs", "commands"), (new_cog_rules, new_cmd_rules)
        ):
            if category in old_rules:
                for name, rules in old_rules[category].items():
                    these_rules = new_rules.setdefault(name, {})
                    guild_rules = these_rules.setdefault(str(guild_id), {})
                    # Since allow rules would take precedence if the same model ID
                    # sat in both the allow and deny list, we add the deny entries
                    # first and let any conflicting allow entries overwrite.
                    for model_id in rules.get("deny", []):
                        guild_rules[str(model_id)] = False
                    for model_id in rules.get("allow", []):
                        guild_rules[str(model_id)] = True
                    if "default" in rules:
                        default = rules["default"]
                        if default == "allow":
                            guild_rules["default"] = True
                        elif default == "deny":
                            guild_rules["default"] = False
    return new_cog_rules, new_cmd_rules


# 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
def _get_updated_schema(
    old_config: _OldConfigSchema,
) -> Tuple[_NewConfigSchema, _NewConfigSchema]:
    # Prior to 1.0.0, the schema was in this form for both global
    # and guild-based rules:
    # "owner_models"
    # -> "cogs"
    #   -> Cog names...
    #     -> "allow"
    #       -> [Model IDs...]
    #     -> "deny"
    #       -> [Model IDs...]
    #     -> "default"
    #       -> "allow"|"deny"
    # -> "commands"
    #   -> Command names...
    #     -> "allow"
    #       -> [Model IDs...]
    #     -> "deny"
    #       -> [Model IDs...]
    #     -> "default"
    #       -> "allow"|"deny"

    new_cog_rules = {}
    new_cmd_rules = {}
    for guild_id, old_rules in old_config.items():
        if "owner_models" not in old_rules:
            continue
        old_rules = old_rules["owner_models"]
        for category, new_rules in zip(
            ("cogs", "commands"), (new_cog_rules, new_cmd_rules)
        ):
            if category in old_rules:
                for name, rules in old_rules[category].items():
                    these_rules = new_rules.setdefault(name, {})
                    guild_rules = these_rules.setdefault(str(guild_id), {})
                    # Since allow rules would take precedence if the same model ID
                    # sat in both the allow and deny list, we add the deny entries
                    # first and let any conflicting allow entries overwrite.
                    for model_id in rules.get("deny", []):
                        guild_rules[str(model_id)] = False
                    for model_id in rules.get("allow", []):
                        guild_rules[str(model_id)] = True
                    if "default" in rules:
                        default = rules["default"]
                        if default == "allow":
                            guild_rules["default"] = True
                        elif default == "deny":
                            guild_rules["default"] = False
    return new_cog_rules, new_cmd_rules