SOLVED: AJAX add to cart strips any field containing "attribute_", breaking Composite Products & Product Bundles

Browser: Chrome 151
OS: macOS
Bricks: 2.3.11
WooCommerce: 11.0.1
WooCommerce Composite Products: 11.1.0
WooCommerce Product Bundles: 8.5.10

Summary

With AJAX add to cart enabled, no Composite Product or Product Bundle can ever be added to the cart. The request returns {"error":true,...}, the browser follows product_url back to the product page, and the cart stays empty with no error message shown to the customer.

This is the same underlying issue as the Aug 2024 report “Woo Composite product cannot be added to cart”. That thread was marked SOLVED with the workaround “disable AJAX add to cart”, but the root cause was never identified and is still present in 2.3.11. Below is the exact cause and a one-line fix.

Root cause

assets/js/integrations/woocommerce.js, in bricksWooAddToCart() — the “third party plugin” passthrough loop added in 1.7.2 (@see #862je3dz8).

Line 1213:

// Populate other data inside the form for third party plugins
for (const pair of formData.entries()) {
    // Skip product_id, quantity, variation_id, add-to-cart, and attributes
    if (
        pair[0] === 'product_id' ||
        pair[0] === 'quantity' ||
        pair[0] === 'variation_id' ||
        pair[0] === 'add-to-cart' ||
        pair[0].indexOf('attribute_') > -1   // <-- unanchored substring match
    ) {
        continue
    }
    ...

The intent is to skip variable-product attribute fields, which are already repacked into data.variation at line 1174. But indexOf(...) > -1 matches the substring anywhere in the field name, so it also silently discards the fields third-party product types depend on:

Plugin Field name Contains attribute_? Starts with it?
Composite Products wccp_attribute_pa_exodus-cap[1679248885] yes no
Product Bundles bundle_attribute_pa_gender_4 yes no

Neither form is a .variations_form, so nothing ever re-adds them. The server receives the component/variation IDs but none of the attribute selections.

Line 1174 has the same unanchored comparison.

Separately, data.product_type is left as 'simple' for these product types (line 1163), which is also inaccurate.

Steps to reproduce

  1. Install WooCommerce Composite Products (or Product Bundles).
  2. Create a composite/bundle containing at least one variable product component.
  3. Enable Bricks’ AJAX add to cart.
  4. On the front end, select every required option so the button is enabled and the price resolves.
  5. Click Add to cart.

Expected

Product is added to the cart with its selected options.

Actual

POST /?wc-ajax=bricks_add_to_cart returns HTTP 200 with:

{"error":true,"product_url":"https://example.com/product/exodus-pro-bundle/"}

The page reloads to the product URL and the cart is unchanged. No error is shown to the customer.

Request payload actually sent (note every wccp_attribute_pa_* field is missing):

product_id=27378
quantity=1
product_type=simple
wccp_component_selection[1679248885]=26766
wccp_variation_id[1679248885]=26782
wccp_component_quantity[1679248885]=1
wccp_component_selection[1679248886]=26840
wccp_variation_id[1679248886]=27909
wccp_component_quantity[1679248886]=1
wccp_component_selection[1679248940]=13039
wccp_variation_id[1679248940]=13040
wccp_component_quantity[1679248940]=1

Confirmation that the dropped fields are the cause

Replaying both payloads server-side against WC()->cart->add_to_cart() on the same site:

  • Full native form POST (includes wccp_attribute_pa_*) → adds successfully, cart count 1.
  • Bricks AJAX payload (attributes stripped) → throws:
    "EXODUS Pro Bundle" cannot be added to your cart. "Exodus Options" is a required "EXODUS" field.

The non-AJAX form POST carries the full field set and works correctly, which is why disabling AJAX add to cart “fixes” it.

Suggested fix

Anchor both comparisons so only genuine WooCommerce variation attributes are skipped:

// line 1213
pair[0].startsWith('attribute_')

// line 1174
if (pair[0].startsWith('attribute_')) {

Variable-product attribute fields are always named attribute_* (e.g. attribute_pa_color), so anchoring preserves the existing behaviour for variable products while letting wccp_attribute_* and bundle_attribute_* through to the server.

One correction to the older thread

In the earlier thread it was stated that it isn’t possible to disable AJAX add to cart for a single product type. It is — gating on the product type works fine:

add_action( 'wp_enqueue_scripts', function () {
    if ( ! is_product() ) {
        return;
    }
    global $product;
    if ( ! $product instanceof WC_Product
        || ! in_array( $product->get_type(), array( 'composite', 'bundle' ), true ) ) {
        return;
    }
    wp_add_inline_script(
        'bricks-scripts',
        'if (typeof bricksWooCommerce !== "undefined") { bricksWooCommerce.ajaxAddToCartEnabled = false; }',
        'after'
    );
}, 20 );

That is only a workaround though — it costs the AJAX cart on exactly the highest-value products. The one-line anchoring fix above would resolve it properly.

Hi @bryckroad ,

Thanks for the report. Added it into our bug tracker.
We will update this forum thread once it’s fixed.

Regards,
Jenn

We’ve addressed this in Bricks 2.3.12, now available as a one-click update in your WordPress Dashboard.

Please read the changelog entry before updating, and let us know if you experience any issues.