Magento Tutorials

How to Fix Magento 2 Bulk Actions Not Starting

Bulk actions not starting used to be a common issue on Magento 2.3.x and lower versions. And while there’s a fix for this bug in Magento development branches, it still requires a bit of manual work to implement the fix into your Magento store.

In this article, we will be digging into this bug and offer you solutions to help you deal with this issue:

Steps to reproduce

This actually is an easily reproducible bug, which is part of the reason why it’s so popular. 

  1. In your Magento 2 Admin, go to Catalog > Products

Catalog Products menu

2. Select All Products and in Actions, choose Update attributes

Bulk Update Product Attributes

3. Update a product attribute. For demonstration purposes, we’ll be updating product descriptions.

Bulk updating descriptions

4. Click on Save and you’ll see that, despite selecting several products, 0 item has been scheduled for update.

Notification 0 items have been scheduled for update

And when you check Bulk Actions Log (in System > Action Logs > Bulk Actions), it’ll show that the bulk action jobs we previously apply are not started:

Bulk Actions Not Started

Further clicking on Details and you’ll see that our bulk actions seem to be stuck in the “Pending, in queue…” mode.

Solutions

There are several ways using which you can get around this bug. Here are several methods to try if the bug is resolved for you.

For Magento 2.4.x and above

For Magento 2.4.x and above, there’s a fix on Magento development branches which requires you to go into:

vendor/magento/module-asynchronous-operations/etc/

And make a duplicate of db_schema.xml. You’ll want to replace the content of this file with the following code:

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
    <table name="magento_bulk" resource="default" engine="innodb"
           comment="Bulk entity that represents set of related asynchronous operations">
        <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true"
                comment="Bulk Internal ID (must not be exposed)"/>
        <column xsi:type="varbinary" name="uuid" nullable="true" length="39"
                comment="Bulk UUID (can be exposed to reference bulk entity)"/>
        <column xsi:type="int" name="user_id" padding="10" unsigned="true" nullable="true" identity="false"
                comment="ID of the WebAPI user that performed an action"/>
        <column xsi:type="int" name="user_type" nullable="true" comment="Which type of user"/>
        <column xsi:type="varchar" name="description" nullable="true" length="255" comment="Bulk Description"/>
        <column xsi:type="int" name="operation_count" padding="10" unsigned="true" nullable="false" identity="false"
                comment="Total number of operations scheduled within this bulk"/>
        <column xsi:type="timestamp" name="start_time" on_update="false" nullable="false" default="CURRENT_TIMESTAMP"
                comment="Bulk start time"/>
        <constraint xsi:type="primary" referenceId="PRIMARY">
            <column name="id"/>
        </constraint>
        <constraint xsi:type="unique" referenceId="MAGENTO_BULK_UUID">
            <column name="uuid"/>
        </constraint>
        <index referenceId="MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID" indexType="btree">
            <column name="user_id"/>
        </index>
    </table>
    <table name="magento_operation" resource="default" engine="innodb" comment="Operation entity">
        <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true"
                comment="Operation ID"/>
        <column xsi:type="int" name="operation_key" padding="10" unsigned="true" nullable="true"
                comment="Operation Key"/>
        <column xsi:type="varbinary" name="bulk_uuid" nullable="true" length="39" comment="Related Bulk UUID"/>
        <column xsi:type="varchar" name="topic_name" nullable="true" length="255"
                comment="Name of the related message queue topic"/>
        <column xsi:type="blob" name="serialized_data" nullable="true"
                comment="Data (serialized) required to perform an operation"/>
        <column xsi:type="blob" name="result_serialized_data" nullable="true"
                comment="Result data (serialized) after perform an operation"/>
        <column xsi:type="smallint" name="status" padding="6" unsigned="false" nullable="true" identity="false"
                default="0" comment="Operation status (OPEN | COMPLETE | RETRIABLY_FAILED | NOT_RETRIABLY_FAILED)"/>
        <column xsi:type="smallint" name="error_code" padding="6" unsigned="false" nullable="true" identity="false"
                comment="Code of the error that appeared during operation execution (used to aggregate related failed operations)"/>
        <column xsi:type="varchar" name="result_message" nullable="true" length="255"
                comment="Operation result message"/>
        <constraint xsi:type="primary" referenceId="PRIMARY">
            <column name="id"/>
        </constraint>
        <constraint xsi:type="foreign" referenceId="MAGENTO_OPERATION_BULK_UUID_MAGENTO_BULK_UUID" table="magento_operation"
                    column="bulk_uuid" referenceTable="magento_bulk" referenceColumn="uuid" onDelete="CASCADE"/>
        <index referenceId="MAGENTO_OPERATION_BULK_UUID_ERROR_CODE" indexType="btree">
            <column name="bulk_uuid"/>
            <column name="error_code"/>
        </index>
    </table>
    <table name="magento_acknowledged_bulk" resource="default" engine="innodb"
           comment="Bulk that was viewed by user from notification area">
        <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true"
                comment="Internal ID"/>
        <column xsi:type="varbinary" name="bulk_uuid" nullable="true" length="39" comment="Related Bulk UUID"/>
        <constraint xsi:type="primary" referenceId="PRIMARY">
            <column name="id"/>
        </constraint>
        <constraint xsi:type="foreign" referenceId="MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID_MAGENTO_BULK_UUID"
                    table="magento_acknowledged_bulk" column="bulk_uuid" referenceTable="magento_bulk"
                    referenceColumn="uuid" onDelete="CASCADE"/>
        <constraint xsi:type="unique" referenceId="MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID">
            <column name="bulk_uuid"/>
        </constraint>
    </table>
</schema>

After which, run:

php bin/magento s:up

This should resolve the issue for your newer bulk action jobs (previously stuck bulk action jobs will still remain stuck). 

For Magento 2.3.x and below

For earlier Magento versions (Magento 2.3.x and below), you’ll want to do things in a different way, and there are several ways to do this.

1. Manually run a cron job

The most popular solution for this issue is to manually run a cron job.

php bin/magento cron:run
run a cron job successfully

Or make sure that cron is running properly:

crontab -u <Magento file system owner name> -l

If no crontab has been setup, you’ll see the following messages:

no crontab for magento_user

Your crontab tells you the following:

  • What PHP binary you’re using (in some cases, you have more than one)
  • What Magento cron scripts you’re running (in particular, the paths to those scripts)
  • Where your cron logs are located

After running a cron job, you’ll see that your previous stuck action jobs are finished successfully.

bulk actions finishsed successfully

2. Make changes to cron_consumers_runner in the env.php file

If the above solution doesn’t work for you, you can try editing the env.php file. In this file, look for cron_consumers_runner and replace its content with the following code:

'cron_consumers_runner' => [
     'cron_run' => true,
     'max_messages' => 2000,
     'consumers' => [
         'product_action_attribute.update',
         'product_action_attribute.website.update',
         'exportProcessor',
         'codegeneratorProcessor'
     ]
 ]

If you are not able to find a cron_consumers_runner function in the file, just insert it to the bottom of the env.php file, like so:

replacing cron_consumers_runner

Conclusion

We hope that this article brings you the fix that you need to resolve this issue. If none of the listed solutions works for you, do feel free to let us know in the comment section below so we can work on bringing you better solutions.

Is it helpful?

Luke Vu

A content writer with a passion for the English language.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments