Creating a PMax campaign with brand error (Python)

26 views
Skip to first unread message

Andreas Chouliaras

unread,
Jul 2, 2025, 6:24:11 PM7/2/25
to Google Ads API and AdWords API Forum
Hello,

I am using the following code:

def create_asset_group_operation_brand(
    client,
    customer_id,
    brand_guidelines_enabled,
    creative,
    temp_campaign_id,
    temp_asset_group_id,
    brand,
    next_temp_id
):
    asset_group_service = client.get_service("AssetGroupService")
    campaign_service = client.get_service("CampaignService")
    operations = []

    # 1. Create the AssetGroup (with temp ID)
    mutate_operation = client.get_type("MutateOperation")
    asset_group = mutate_operation.asset_group_operation.create
    asset_group.name = (
        f"Performance Max asset group {datetime.utcnow().isoformat(timespec='seconds')}"
    )
    asset_group.campaign = f"customers/{customer_id}/campaigns/{temp_campaign_id}"
    for url in creative.final_urls:
        asset_group.final_urls.append(url)
    if hasattr(creative, "final_mobile_urls") and creative.final_mobile_urls:
        for url in creative.final_mobile_urls:
            asset_group.final_mobile_urls.append(url)
    asset_group.status = client.enums.AssetGroupStatusEnum.PAUSED
    asset_group.resource_name = asset_group_service.asset_group_path(
        customer_id,
        temp_asset_group_id,
    )
    operations.append(mutate_operation)

    # 2. Use unique negative temp IDs for all nodes
    root_temp_id = next_temp_id
    root_resource_name = f"customers/{customer_id}/assetGroupListingGroupFilters/{temp_asset_group_id}~{root_temp_id}"
    next_temp_id -= 1
    brand_resource_name = f"customers/{customer_id}/assetGroupListingGroupFilters/{temp_asset_group_id}~{next_temp_id}"
    next_temp_id -= 1
    else_resource_name = f"customers/{customer_id}/assetGroupListingGroupFilters/{temp_asset_group_id}~{next_temp_id}"
    next_temp_id -= 1

    # 3. Root: SUBDIVISION (do NOT set parent_listing_group_filter)
    root_lgf_op = client.get_type("MutateOperation")
    root_lgf = root_lgf_op.asset_group_listing_group_filter_operation.create
    root_lgf.asset_group = asset_group.resource_name
    root_lgf.type = client.enums.ListingGroupFilterTypeEnum.SUBDIVISION
    root_lgf.listing_source = client.enums.ListingGroupFilterListingSourceEnum.SHOPPING
    root_lgf.resource_name = root_resource_name
    print("Appending root SUBDIVISION node:", root_lgf.type, getattr(root_lgf, 'case_value', None))
    operations.append(root_lgf_op)

    # 4. Child 1: UNIT_INCLUDED for the given brand
    brand_lgf_op = client.get_type("MutateOperation")
    brand_lgf = brand_lgf_op.asset_group_listing_group_filter_operation.create
    brand_lgf.asset_group = asset_group.resource_name
    brand_lgf.type = client.enums.ListingGroupFilterTypeEnum.UNIT_INCLUDED
    brand_lgf.listing_source = client.enums.ListingGroupFilterListingSourceEnum.SHOPPING
    brand_lgf.resource_name = brand_resource_name
    brand_lgf.parent_listing_group_filter = root_resource_name
    # Explicitly instantiate nested fields
    brand_lgf.case_value = client.get_type("ListingGroupFilterDimension")
    brand_lgf.case_value.product_brand = client.get_type("ListingGroupFilterDimension.ProductBrand")
    brand_lgf.case_value.product_brand.value = brand
    print("DEBUG: brand_lgf.case_value:", brand_lgf.case_value)
    print("DEBUG: brand_lgf.case_value.product_brand:", brand_lgf.case_value.product_brand)
    print("Appending UNIT_INCLUDED node:", brand_lgf.type, brand_lgf.case_value)
    operations.append(brand_lgf_op)

    # 5. Child 2: UNIT_EXCLUDED for everything else
    else_lgf_op = client.get_type("MutateOperation")
    else_lgf = else_lgf_op.asset_group_listing_group_filter_operation.create
    else_lgf.asset_group = asset_group.resource_name
    else_lgf.type = client.enums.ListingGroupFilterTypeEnum.UNIT_EXCLUDED
    else_lgf.listing_source = client.enums.ListingGroupFilterListingSourceEnum.SHOPPING
    else_lgf.resource_name = else_resource_name
    else_lgf.parent_listing_group_filter = root_resource_name
    # DO NOT reference or set case_value for UNIT_EXCLUDED
    print("Appending UNIT_EXCLUDED node:", else_lgf.type)
    operations.append(else_lgf_op)

    # Focused debug printout of all listing group filter nodes before returning
    print("\n==== Listing Group Filter Focused Debug ====")
    type_counts = {}
    for op in operations:
        if hasattr(op, 'asset_group_listing_group_filter_operation') and op.asset_group_listing_group_filter_operation:
            node = op.asset_group_listing_group_filter_operation.create
            node_type = node.type
            type_str = str(node_type)
            type_counts[type_str] = type_counts.get(type_str, 0) + 1
            print(f"resource_name: {getattr(node, 'resource_name', None)}")
            print(f"  type: {type_str}")
            print(f"  parent_listing_group_filter: {getattr(node, 'parent_listing_group_filter', None)}")
            # Only print case_value.brand if set
            if node_type == client.enums.ListingGroupFilterTypeEnum.UNIT_INCLUDED:
                brand_val = getattr(getattr(node.case_value, 'product_brand', None), 'value', None)
                print(f"  case_value.brand: {brand_val}")
            else:
                print(f"  case_value.brand: (not set)")
    print("Node type counts:", type_counts)
    print("==== END FOCUSED DEBUG ====")

    return operations, next_temp_id




and I am getting the following error:



{ "detail": "(<_InactiveRpcError of RPC that terminated with:\n\tstatus = StatusCode.INVALID_ARGUMENT\n\tdetails = \"Request contains an invalid argument.\"\n\tdebug_error_string = \"UNKNOWN:Error received from peer ipv4:142.250.186.74:443 {created_time:\"2025-07-02T11:29:23.575456404+00:00\", grpc_status:3, grpc_message:\"Request contains an invalid argument.\"}\"\n>, <_InactiveRpcError of RPC that terminated with:\n\tstatus = StatusCode.INVALID_ARGUMENT\n\tdetails = \"Request contains an invalid argument.\"\n\tdebug_error_string = \"UNKNOWN:Error received from peer ipv4:142.250.186.74:443 {created_time:\"2025-07-02T11:29:23.575456404+00:00\", grpc_status:3, grpc_message:\"Request contains an invalid argument.\"}\"\n>, errors {\n error_code {\n asset_group_listing_group_filter_error: SUBDIVISION_MUST_HAVE_EVERYTHING_ELSE_CHILD\n }\n message: \"Listing Group SUBDIVISION node must have everything else child.\"\n trigger {\n int64_value: -4\n }\n location {\n field_path_elements {\n field_name: \"mutate_operations\"\n index: 6\n }\n field_path_elements {\n field_name: \"asset_group_listing_group_filter_operation\"\n }\n field_path_elements {\n field_name: \"create\"\n }\n field_path_elements {\n field_name: \"type\"\n }\n }\n}\nerrors {\n error_code {\n field_error: REQUIRED\n }\n message: \"The required field was not present.\"\n location {\n field_path_elements {\n field_name: \"mutate_operations\"\n index: 8\n }\n field_path_elements {\n field_name: \"asset_group_listing_group_filter_operation\"\n }\n field_path_elements {\n field_name: \"create\"\n }\n field_path_elements {\n field_name: \"case_value\"\n }\n }\n}\nrequest_id: \"mOWHJw8mf6f5mvoe-m13uw\"\n, 'mOWHJw8mf6f5mvoe-m13uw')" }



does anyone know what I need to change in my code to stop getting this error?


Google Ads API Forum Advisor

unread,
Jul 2, 2025, 11:24:57 PM7/2/25
to adh...@gmail.com, adwor...@googlegroups.com

Hi,

Thank you for reaching out to the Google Ads API support team.

From the provided information, I could see that you are encountering a 'SUBDIVISION_MUST_HAVE_EVERYTHING_ELSE_CHILD' error. The SUBDIVISION_MUST_HAVE_EVERYTHING_ELSE_CHILD error, which means that a subdivision introduces a new level in the tree, while units are the leaves of the tree. Each subdivision must always be completely partitioned, so it must contain a node representing 'Other'. In the example provided in the document, the root and Product Condition: (Other) nodes are subdivisions. This tree structure with subdivisions and units lets you set bids at the unit level and also ensures that every product falls into one and only one unit node in the tree.

I hope this helps. If you have any more queries, please feel free to get back to us.

 

Thanks,
 
Google Logo Google Ads API Team

Feedback
How was our support today?

rating1    rating2    rating3    rating4    rating5
[2025-07-03 03:23:33Z GMT] This message is in relation to case "ref:!00D1U01174p.!500Ht01rh6aL:ref" (ADR-00316865)



Reply all
Reply to author
Forward
0 new messages