# Buggy code
def live_ability(converter_group, line, container_obj_ref, diff=None):
    """
    Creates a patch for the Live ability of a line.

    :param converter_group: Group that gets the patch.
    :type converter_group: ...dataformat.converter_object.ConverterObjectGroup
    :param line: Unit/Building line that has the ability.
    :type line: ...dataformat.converter_object.ConverterObjectGroup
    :param container_obj_ref: Reference of the raw API object the patch is nested in.
    :type container_obj_ref: str
    :param diff: A diff between two ConvertObject instances.
    :type diff: ...dataformat.converter_object.ConverterObject
    :returns: The forward references for the generated patches.
    :rtype: list
    """
    head_unit_id = line.get_head_unit_id()
    tech_id = converter_group.get_id()
    dataset = line.data

    patches = []

    name_lookup_dict = internal_name_lookups.get_entity_lookups(dataset.game_version)
    tech_lookup_dict = internal_name_lookups.get_tech_lookups(dataset.game_version)

    game_entity_name = name_lookup_dict[head_unit_id][0]

    if diff:
        diff_hp = diff["hit_points"]
        if isinstance(diff_hp, NoDiffMember):
            return patches

        diff_hp_value = diff_hp.get_value()

    else:
        return patches

    patch_target_ref = f"{game_entity_name}.Live.Health"
    patch_target_forward_ref = ForwardRef(line, patch_target_ref)

    # Wrapper
    wrapper_name = f"Change{game_entity_name}HealthWrapper"
    wrapper_ref = f"{container_obj_ref}.{wrapper_name}"
    wrapper_raw_api_object = RawAPIObject(
        wrapper_ref, wrapper_name, dataset.nyan_api_objects
    )
    wrapper_raw_api_object.add_raw_parent("engine.aux.patch.Patch")

    if isinstance(line, GenieBuildingLineGroup):
        # Store building upgrades next to their game entity definition,
        # not in the Age up techs.
        wrapper_raw_api_object.set_location(
            "data/game_entity/generic/%s/" % (name_lookup_dict[head_unit_id][1])
        )
        wrapper_raw_api_object.set_filename(f"{tech_lookup_dict[tech_id][1]}_upgrade")

    else:
        wrapper_raw_api_object.set_location(
            ForwardRef(converter_group, container_obj_ref)
        )

    # Nyan patch
    nyan_patch_name = f"Change{game_entity_name}Health"
    nyan_patch_ref = f"{container_obj_ref}.{wrapper_name}.{nyan_patch_name}"
    nyan_patch_location = ForwardRef(converter_group, wrapper_ref)
    nyan_patch_raw_api_object = RawAPIObject(
        nyan_patch_ref, nyan_patch_name, dataset.nyan_api_objects, nyan_patch_location
    )
    nyan_patch_raw_api_object.add_raw_parent("engine.aux.patch.NyanPatch")
    nyan_patch_raw_api_object.set_patch_target(patch_target_forward_ref)

    # HP max value
    nyan_patch_raw_api_object.add_raw_patch_member(
        "max_value",
        diff_hp_value,
        "engine.aux.attribute.AttributeSetting",
        MemberOperator.ADD,
    )

    patch_forward_ref = ForwardRef(converter_group, nyan_patch_ref)
    wrapper_raw_api_object.add_raw_member(
        "patch", patch_forward_ref, "engine.aux.patch.Patch"
    )

    converter_group.add_raw_api_object(wrapper_raw_api_object)
    converter_group.add_raw_api_object(nyan_patch_raw_api_object)

    wrapper_forward_ref = ForwardRef(converter_group, wrapper_ref)
    patches.append(wrapper_forward_ref)

    return patches


# Traceback (KeyError)
INFO [py] launching openage v0.4.1-377-g2be30ba76
INFO [py] compiled by GNU 10.2.0
Do you want to convert assets? [Y/n]
Y
Should we call wine to determine an AOE installation? [Y/n]
n
Could not find any installation directory automatically.
Please enter an AOE2 install path manually.
/home/schatzi/nvme/Steam/steamapps/common/AoE2DE/
converting from '/home/schatzi/nvme/Steam/steamapps/common/AoE2DE'
INFO [py] Game edition detected:
INFO [py]  * Age of Empires 2: Definitive Edition
INFO [py] converting metadata
INFO [py] [0] palette
INFO [py] [1] empires.dat
INFO [py] Starting conversion...
INFO [py] Extracting Genie data...
INFO [py] Creating API-like objects...
INFO [py] Linking API-like objects...
INFO [py] Generating auxiliary objects...
INFO [py] Creating nyan objects...
Traceback (most recent call last):
File "/usr/bin/openage", line 15, in <module>
main()
File "/usr/lib/python3.9/site-packages/openage/__main__.py", line 132, in main
return args.entrypoint(args, cli.error)
File "/usr/lib/python3.9/site-packages/openage/game/main.py", line 71, in main
used_asset_path = convert_assets(
File "/usr/lib/python3.9/site-packages/openage/convert/main.py", line 100, in convert_assets
for current_item in convert(args):
File "/usr/lib/python3.9/site-packages/openage/convert/tool/driver.py", line 48, in convert
yield from convert_metadata(args)
File "/usr/lib/python3.9/site-packages/openage/convert/tool/driver.py", line 96, in convert_metadata
modpacks = args.converter.convert(gamespec,
File "/usr/lib/python3.9/site-packages/openage/convert/processor/conversion/de2/processor.py", line 63, in convert
modpacks = cls._post_processor(dataset)
File "/usr/lib/python3.9/site-packages/openage/convert/processor/conversion/de2/processor.py", line 153, in _post_processor
DE2NyanSubprocessor.convert(full_data_set)
File "/usr/lib/python3.9/site-packages/openage/convert/processor/conversion/de2/nyan_subprocessor.py", line 38, in convert
cls._process_game_entities(gamedata)
File "/usr/lib/python3.9/site-packages/openage/convert/processor/conversion/de2/nyan_subprocessor.py", line 120, in _process_game_entities
cls.tech_group_to_tech(tech_group)
File "/usr/lib/python3.9/site-packages/openage/convert/processor/conversion/de2/nyan_subprocessor.py", line 596, in tech_group_to_tech
patches.extend(DE2TechSubprocessor.get_patches(tech_group))
File "/usr/lib/python3.9/site-packages/openage/convert/processor/conversion/de2/tech_subprocessor.py", line 147, in get_patches
patches.extend(cls.resource_modify_effect(converter_group,
File "/usr/lib/python3.9/site-packages/openage/convert/processor/conversion/de2/tech_subprocessor.py", line 276, in resource_modify_effect
upgrade_func = DE2TechSubprocessor.upgrade_resource_funcs[resource_id]
KeyError:  208

# Fixed code
def live_ability(converter_group, line, container_obj_ref, diff=None):
    """
    Creates a patch for the Live ability of a line.

    :param converter_group: Group that gets the patch.
    :type converter_group: ...dataformat.converter_object.ConverterObjectGroup
    :param line: Unit/Building line that has the ability.
    :type line: ...dataformat.converter_object.ConverterObjectGroup
    :param container_obj_ref: Reference of the raw API object the patch is nested in.
    :type container_obj_ref: str
    :param diff: A diff between two ConvertObject instances.
    :type diff: ...dataformat.converter_object.ConverterObject
    :returns: The forward references for the generated patches.
    :rtype: list
    """
    head_unit_id = line.get_head_unit_id()
    tech_id = converter_group.get_id()
    dataset = line.data

    patches = []

    name_lookup_dict = internal_name_lookups.get_entity_lookups(dataset.game_version)
    tech_lookup_dict = internal_name_lookups.get_tech_lookups(dataset.game_version)

    game_entity_name = name_lookup_dict[head_unit_id][0]

    if diff:
        diff_hp = diff["hit_points"]
        if isinstance(diff_hp, NoDiffMember):
            return patches

        diff_hp_value = diff_hp.get_value()

    else:
        return patches

    patch_target_ref = f"{game_entity_name}.Live.Health"
    patch_target_forward_ref = ForwardRef(line, patch_target_ref)

    # Wrapper
    wrapper_name = f"Change{game_entity_name}HealthWrapper"
    wrapper_ref = f"{container_obj_ref}.{wrapper_name}"
    wrapper_raw_api_object = RawAPIObject(
        wrapper_ref, wrapper_name, dataset.nyan_api_objects
    )
    wrapper_raw_api_object.add_raw_parent("engine.aux.patch.Patch")

    if isinstance(line, GenieBuildingLineGroup):
        # Store building upgrades next to their game entity definition,
        # not in the Age up techs.
        wrapper_raw_api_object.set_location(
            "data/game_entity/generic/%s/" % (name_lookup_dict[head_unit_id][1])
        )
        wrapper_raw_api_object.set_filename(f"{tech_lookup_dict[tech_id][1]}_upgrade")

    else:
        wrapper_raw_api_object.set_location(
            ForwardRef(converter_group, container_obj_ref)
        )

    # Nyan patch
    nyan_patch_name = f"Change{game_entity_name}Health"
    nyan_patch_ref = f"{container_obj_ref}.{wrapper_name}.{nyan_patch_name}"
    nyan_patch_location = ForwardRef(converter_group, wrapper_ref)
    nyan_patch_raw_api_object = RawAPIObject(
        nyan_patch_ref, nyan_patch_name, dataset.nyan_api_objects, nyan_patch_location
    )
    nyan_patch_raw_api_object.add_raw_parent("engine.aux.patch.NyanPatch")
    nyan_patch_raw_api_object.set_patch_target(patch_target_forward_ref)

    # HP max value
    nyan_patch_raw_api_object.add_raw_patch_member(
        "max_value",
        diff_hp_value,
        "engine.aux.attribute.AttributeSetting",
        MemberOperator.ADD,
    )

    # HP starting value
    nyan_patch_raw_api_object.add_raw_patch_member(
        "starting_value",
        diff_hp_value,
        "engine.aux.attribute.AttributeSetting",
        MemberOperator.ADD,
    )

    patch_forward_ref = ForwardRef(converter_group, nyan_patch_ref)
    wrapper_raw_api_object.add_raw_member(
        "patch", patch_forward_ref, "engine.aux.patch.Patch"
    )

    converter_group.add_raw_api_object(wrapper_raw_api_object)
    converter_group.add_raw_api_object(nyan_patch_raw_api_object)

    wrapper_forward_ref = ForwardRef(converter_group, wrapper_ref)
    patches.append(wrapper_forward_ref)

    return patches