“Action Scheduler: 7 past-due actions found; something may be wrong.” If you run WooCommerce or any plugin that bundles Action Scheduler (many email, subscription, backup and SEO plugins do), you’ve probably seen this notice in wp-admin. In a thread on the WordPress.org forums this week, users saw a broken version of it: a raw %1$d where the number should be and a link that goes nowhere.
There are two separate problems here, and I’ll fix both. The broken text is a bug in older Action Scheduler versions. A real number of past-due actions means your queue isn’t running, and that one matters more: it’s the reason order emails, subscription renewals and webhooks show up late or not at all.
Step 1: Find which copy of Action Scheduler is loaded
Action Scheduler isn’t part of WordPress core. It’s a library that plugins bundle, and when several plugins ship it, the newest version wins. The broken %1$d notice was fixed in Action Scheduler 4.2.0, whose changelog says: “Show the number of actions and the link in the past-due actions admin notice, instead of raw placeholders.”
WP-CLI shows the active version and which plugin it’s loaded from:
wp action-scheduler version
wp action-scheduler version --all
wp action-scheduler source --all --fullpath
If the active version is below 4.2.0, update the plugin that provides it (often WooCommerce) or any other plugin that bundles a newer copy. The source command was added in Action Scheduler 3.9.1, so on very old copies it won’t exist. That alone tells you it’s time to update. No WP-CLI yet? See Install WP-CLI on cPanel shared hosting.
Step 2: Check whether the queue is actually stuck
A correct notice with a real number means pending actions whose scheduled time has already passed. Look at the queue:
wp action-scheduler status
wp action-scheduler action list --status=pending --format=count
wp action-scheduler action list --status=pending --fields=id,hook,group,scheduled_date --per_page=20
status prints the data store, the runner, the version and a count per status with the oldest and newest dates. If the oldest pending action is hours or days old, the queue runner isn’t firing. You can also see this in wp-admin under Tools → Scheduled Actions, filtered to Past-due.
Step 3: Clear the backlog with WP-CLI
Back up the database first. Running the queue sends any emails, renewals and webhooks that were waiting.
wp db export ~/before-as-run-$(date +%F).sql
# Process everything that is due, 100 actions per batch, until the queue is empty
wp action-scheduler run --batch-size=100 --batches=0
# Or just one group or hook (take the names from the "action list" output above)
wp action-scheduler run --group=your-group-name
wp action-scheduler run --hooks=your_hook_name
These flags come from the official Action Scheduler WP-CLI docs. --batches=0 keeps running until no actions are left. If it reports that too many queues are already running, --force overrides the concurrency limit. Use it once, not in a cron job.
Keep the export outside the web root, and delete it when you’re done. If the actions and logs tables have grown huge, clean them up afterwards with my guide to the wp_actionscheduler_actions and wp_actionscheduler_logs tables.
Step 4: Make the queue run on a real cron
The backlog comes back unless you fix the trigger. Action Scheduler hooks its runner into WP-Cron as action_scheduler_run_queue on an every_minute schedule. WP-Cron only fires when someone visits the site, so it’s unreliable on low-traffic sites, and full-page caching or a firewall blocking wp-cron.php can stop it entirely. The fix is the same one I use for the Missed Schedule error: disable the visitor-triggered cron and use a server cron instead.
In wp-config.php, above the “That’s all, stop editing!” line:
define( 'DISABLE_WP_CRON', true );
Then add a system cron job (crontab -e as the site user, not root):
# WP-Cron events every 5 minutes
*/5 * * * * cd /var/www/example.com && wp cron event run --due-now --quiet
# Action Scheduler queue every minute (busy WooCommerce stores)
* * * * * cd /var/www/example.com && wp action-scheduler run --batch-size=50 --quiet
For a small shop the first line is enough, because action_scheduler_run_queue is a normal cron event. On stores with a lot of orders or subscriptions, the second line works through the queue faster and avoids web request timeouts, which is what the Action Scheduler docs recommend for large sites. If you only have shared hosting without WP-CLI, use wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1 instead. A real cron also gets rid of the ?doing_wp_cron URLs I explained here.
Doing this in OpenPanel vs cPanel
In cPanel you add the line under Cron Jobs and usually point it at php wp-cron.php or a WP-CLI binary you installed yourself. In OpenPanel, WP-CLI is preinstalled in each site’s PHP container. Their WP-CLI guide shows exactly this setup: add DISABLE_WP_CRON, then create a cron job on the PHP container that runs wp cron event run --due-now --path=/var/www/html/example.com --allow-root every 5 minutes. The Run button lets you test the job right away and see its output, which is handy before you rely on it.
Why this works
The past-due notice counts pending actions whose scheduled time is already in the past. Updating to Action Scheduler 4.2.0 or later fixes how the message is displayed. Running the queue from WP-CLI clears the backlog without web request time limits. A server cron makes sure action_scheduler_run_queue fires every few minutes whether or not anyone visits the site, so the notice doesn’t come back.
Prevention
- Keep WooCommerce and other Action Scheduler plugins updated, and run
wp action-scheduler version --allafter big updates to see which copy wins. - Use a server cron on every production site. Visitor-triggered WP-Cron and full-page caching don’t mix well.
- Watch for failed actions too:
wp action-scheduler action list --status=failed --format=count. A failing hook usually points to one specific plugin. - If a security plugin or WAF blocks
wp-cron.php, either allow it or switch to the WP-CLI cron above, which doesn’t go over HTTP at all.
TL;DR
A raw %1$d in the Action Scheduler notice is a display bug fixed in Action Scheduler 4.2.0, so update the plugin that bundles it. A real past-due count means your queue isn’t running. Back up, clear it with wp action-scheduler run --batches=0, then set DISABLE_WP_CRON and run wp cron event run --due-now (or wp action-scheduler run) from a server cron. As of 2026-10-29, those are the current commands and 4.2.0 is the fixed version.

