loop – Reset WooCommerce query when AJAX filters become unchecked

I’ve created an AJAX taxonomy(product_cat) filter that’s used on my WooCommerce product archive page (archive-product.php). The page loads the normal WooCommerce shop loop onload:

woocommerce_product_loop_start();

if (wc_get_loop_prop('total')) {
    while (have_posts()) {
        the_post();

        /**
         * Hook: woocommerce_shop_loop.
         *
         * @hooked WC_Structured_Data::generate_product_data() - 10
         */
        do_action('woocommerce_shop_loop');

        wc_get_template_part('content', 'product');
    }
}

woocommerce_product_loop_end();

The page loads correctly, showing all products. The filter also works great. It filters one or more taxonomies correctly.

The problem is when I uncheck all the checkboxes. I want it to clear any filters and show all products again. Instead, I currently get an error:

POST .../wp-admin/admin-ajax.php 500

The relevant product filter js:

function handleFilterCheckboxesChange(event) {
    const data = {
        action: 'wpf_update_products',
        filters: get_current_filters()
    };
    $.ajax({
        type: 'POST',
        url: '/wp-admin/admin-ajax.php',
        data: data,
        success: function (res) {
            console.log("AJAX Success: ", data.filters); <--- When any filters are checked, this correctly outputs the updated `filters` array: ("example_category_slug")
            $('.products').html(res);
        },
        error: function (err) {
            console.error("AJAX Error: ", data.filters); <--- After all filters are unchecked, ajax fails but this outputs the expected empty array: ()
        }
    });

    $(document.body).trigger('post-load');
}

function get_current_filters() {
    const checkboxes = $('.product-cat-filter-checkbox').get();
    let checked = ();
    for (let i = 0; i < checkboxes.length; i++) {
        if (checkboxes(i).checked) {
            checked.push(checkboxes(i).id);
        };
    }
    return checked;
}

The server-side action:

function wpf_update_products() {
    $args = (
        'post_type'      => 'product',
        'posts_per_page' => 20,
        'post_status'    => 'publish',
    );

    if (!empty($_POST('filters'))) {
        $args('tax_query')() = (
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
            'terms'    => $_POST('filters'),
            'operator' => 'IN'
        );
    } else { // <--- Tried using this to "reset" the query when no filters checked, but still getting error
        $terms = get_terms('product_cat');
        $args('tax_query')() = (
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
            'terms'    => $terms,
            'operator' => 'IN'
        );
    }

    $ajax_query = new WP_Query($args);
    $response = '';

    if ($ajax_query->have_posts()) {
        ob_start();
        while ($ajax_query->have_posts()) : $ajax_query->the_post();
            $response .= wc_get_template_part('content', 'product');
        endwhile;
        $output = ob_get_contents();
        ob_end_clean();
        wp_reset_postdata();
    } else {
        echo __('Sorry, there are no products that fit your query.', 'wpf');
    }
    echo $output;
    die();
}

…hooked from the same class:

add_action('wp_ajax_wpf_update_products', array($this, 'wpf_update_products'));
add_action('wp_ajax_nopriv_wpf_update_products', array($this, 'wpf_update_products'));

Can’t figure out why it’s returning with a 500 error if I’m handling the empty $_POST('filters') on the server side. Can anyone see what I’m missing?