Repository navigation
visualizer_schedule_refresh_db remains missing after Visualizer reactivation #1384
Description
Summary
Visualizer's recurring database-refresh action can remain absent after the plugin is deactivated and reactivated. Reactivation is expected to register visualizer_schedule_refresh_db, as documented, but the reported installation still has no scheduled action afterward. Database-backed charts therefore lack their recurring refresh trigger and may remain stale until manually refreshed.
Customer context
- Product / area: Visualizer scheduled database refresh
- Version: Visualizer 4.0.8; Visualizer Pro 2.0.2
- Environment: WordPress 7.1.1; PHP 8.3.24; single-site status not explicitly confirmed
- Integration / third party: Bundled Action Scheduler 3.9.3
- Reported error / symptom:
visualizer_schedule_refresh_dbis missing after a deactivate/reactivate cycle; no scheduling error appears in the available Visualizer log - Impact: Scheduled database-chart refreshes have no recurring trigger
- Integrity: Diagnostics reported that the installed free and Pro plugin files match their official releases
Reproduction notes
- Use Visualizer 4.0.8 with Visualizer Pro 2.0.2 and a database chart that depends on scheduled refreshes.
- Observe that
visualizer_schedule_refresh_dbis absent underTools > Scheduled Actions. - Deactivate and reactivate Visualizer once, following the product documentation.
- Return to
Tools > Scheduled Actionsand search for the hook. - Reported result: the action remains missing while other WordPress and plugin scheduled tasks work.
This is a customer-verified runtime reproduction. Repository inspection confirms a lifecycle path that can leave both schedulers empty, but the exact Action Scheduler state that triggered this installation's failure was not captured.
Diagnosis
Conclusion
The released lifecycle code has a confirmed gap that can produce and preserve the reported state. On the Action Scheduler path, Visualizer checks only whether a next action is reported, does not inspect the result of recurring-action creation, clears the WP-Cron fallback, and returns. If registration yields no usable action, both scheduling systems can be empty. Ordinary requests do not recreate the action, and the upgrade path runs only when a legacy WP-Cron event exists. The customer's intact 4.0.8 installation remained without the action after the documented reactivation procedure.
Where this likely occurs
classes/Visualizer/Module/Setup.php—Visualizer_Module_Setup::__construct()lines 42-58 registers activation/deactivation and the refresh callback but no recurring-action recovery hook.classes/Visualizer/Module/Setup.php—Visualizer_Module_Setup::activate_on_site()lines 211-218 invokes recurring-action registration during activation.classes/Visualizer/Module/Setup.php—Visualizer_Module_Setup::schedule_refresh_db_action()lines 486-504 callsas_next_scheduled_action(), conditionally callsas_schedule_recurring_action(), then clears the WP-Cron event without checking whether a usable Action Scheduler record was created.classes/Visualizer/Module/Setup.php—Visualizer_Module_Setup::unschedule_refresh_db_action()lines 509-516 removes both Action Scheduler and WP-Cron registrations during deactivation.classes/Visualizer/Module/Upgrade.php—Visualizer_Module_Upgrade::upgrade()lines 18-40 invokes migration only whenwp_next_scheduled()finds a legacy event, leaving the both-missing state untouched.classes/Visualizer/Module/Upgrade.php—Visualizer_Module_Upgrade::migrate_action_scheduler()lines 86-103 similarly clears WP-Cron after attempting Action Scheduler registration without validating the resulting action.index.php—visualizer_launch()lines 148-157 loads the bundled Action Scheduler entry point when the release artifact contains it.- Commit
bc14d4b8introduced the Action Scheduler migration afterv3.11.15; the affected behavior is present in released tagv4.0.8. This establishes the code history but does not by itself prove the customer's exact failure is a regression.
Engineering notes
- The free plugin owns
visualizer_schedule_refresh_db; the Pro add-on manages a separatevisualizer_schedule_importaction and does not override this lifecycle. - Action Scheduler 3.9.3 exposes a recurring-action assurance mechanism, but no corresponding Visualizer registration was found in v4.0.8.
- Action Scheduler's documented API indicates scheduling calls can return a zero action ID when creation fails. The release path does not distinguish that outcome before removing the fallback.
- An exact storage-level failure or stale Action Scheduler status has not been captured from the affected installation, so the immediate runtime trigger remains unknown.
- Open issue Action Scheduler async queue crashes on WordPress 5.3 with
wpdb::db_server_info()error #1361 was read and rejected as a duplicate: it concerns awpdb::db_server_info()fatal on WordPress 5.3, not a missing action on WordPress 7.1.1. - Merged commit
1880fdd8is not in a release tag and adds recovery only when Action Scheduler is unavailable; its inspected branch returns early when Action Scheduler is usable, so it does not establish that this WordPress 7.1.1 report is already fixed.
Test coverage status
tests/test-import.php checks that the custom ten-minute interval exists, and tests/test-schedule.php covers scheduled import behavior. No relevant coverage was found during inspection for activation/deactivation registration, failed Action Scheduler creation, migration with both schedulers empty, or recovery of a missing visualizer_schedule_refresh_db action. The inspected Visualizer Pro scheduler tests concern the separate import action.
What to verify or explore next
- Reproduce with released Visualizer 4.0.8 and Action Scheduler 3.9.3 by removing all
visualizer_schedule_refresh_dbrecords, then running the documented deactivate/reactivate sequence. - Inspect all Action Scheduler statuses and logs for the Visualizer group immediately before and after reactivation.
- Capture the return value and resulting stored record from the recurring-action registration call during activation.
- Run activation, deactivation, migration, and both-missing recovery scenarios on single-site and multisite installations.
- Confirm behavior when another active plugin supplies a different Action Scheduler version.
Unknowns / follow-up
- The affected site's full Action Scheduler status inventory and system information were not available.
- It is unknown whether a stale, failed, canceled, or in-progress record influenced the next-action lookup.
- No local runtime reproduction was performed because the checkout lacks the built
vendor/directory and a matching WordPress test environment.
Confidence
Confidence: 88/100
The affected released code can leave the recurring refresh action absent: it does not verify Action Scheduler registration succeeded, clears the WP-Cron fallback on the Action Scheduler path, and has no recovery check when both records are missing. The customer reproduced the missing action after the documented reactivation procedure with release files verified intact.
Source: HelpScout #3456322130
Generated by bug-report-triage (ID: bug-report-triage_6aaf4c4cab58b6.52292839)
Activity
milicavs commentedon Sep 21, 2026
Update after hands-on investigation on the reporting site (HelpScout 3456322130). The original premise of this issue needs correcting, but a real defect in the same area was confirmed and reproduced live.
Correction
Reactivation DID restore
visualizer_schedule_refresh_db. The site's Action Scheduler data shows the action created at the customer's reactivation (2026-09-19 18:13:38 UTC) and completing every 10 minutes since (238 records at the time of checking). The customer believed it was still missing because they checked WP Crontrol's Cron Events, where the task no longer appears after the WP-Cron to Action Scheduler migration. The docs article for the scheduled database refresh should be updated to point at Tools > Scheduled Actions instead.Confirmed defect: a killed run permanently ends the recurring chain
What actually broke on this site, verified live:
schedule_next_instance(). If PHP dies mid run (host kill, fatal, timeout), AS marks the action failed after 300s in-progress and no new occurrence is ever created. Bothvisualizer_schedule_refresh_db(free) andvisualizer_schedule_import(Pro) stop permanently and silently.Visualizer_Module_Upgrade::upgrade()only migrates when a legacy WP-Cron event exists, and nothing at request time checks whether the recurring action is still scheduled.Recommended fix
Hook Action Scheduler 3.9.3's daily
action_scheduler_ensure_recurring_actionshook (added for exactly this scenario) and re-register the action whenas_next_scheduled_action()returns false:The same applies to
visualizer_schedule_importin Pro. Additionally,schedule_refresh_db_action()should check the return value ofas_schedule_recurring_action()(it returns 0 on failure) before clearing the WP-Cron fallback.Two further Pro-side defects found during the same investigation (unbounded backlog processing in one run, and interval -1 making charts due on every run) are filed in the Pro repo.
Site remediated with a watchdog snippet re-registering both actions; verified working on the customer site 2026-09-21.
fix: recover the refresh chain a killed run ends, and throttle the check
milicavs commentedon Sep 22, 2026
🤖 Automated QA Repro Steps
Database charts refresh on a recurring 10-minute schedule. If one of those runs is cut off mid-flight — a host kill, a PHP timeout, a fatal — the schedule stops for good: no further run is ever created, database charts silently go stale, and nothing in the UI reports it. (The title's premise was corrected during investigation: reactivation does restore the schedule. The customer was looking at WP Crontrol → Cron Events, where the task no longer appears since the move to Action Scheduler — it lives under Tools → Scheduled Actions now.)
This can't be triggered through normal use; it needs a run to die mid-flight, so the snippet below kills one the way a host would.
Requires: the Code Snippets plugin, and at least one chart built from a database query.
Reproduce on Visualizer 4.0.8:
visualizer_schedule_refresh_db, and note the one pending action and its ID./wp-admin/?vis_kill=1— the page prints the killed action ID.visualizer_schedule_refresh_dbagain.visualizer_schedule_refresh_dbis back with a new ID, due immediately and repeating every 10 minutes; the chart's data updates again on the next run.Edge cases
visualizer_schedule_importis a separate Pro-owned action and is not covered by this fix — don't treat it as a failure here.Fix: #1385 (open)
pirate-bot commentedon Sep 25, 2026
QA agent — 🟡 Needs human QA · Killed database-refresh runs recover and update charts; failed scheduling retains a working fallback.
A simulated killed refresh left no successor, then an ordinary admin page restored one recurring action; running it updated the database chart and its next-refresh time. Daily assurance, recovery west of UTC, repeated kills, and fallback after Action Scheduler refused a new action all behaved as expected. Documentation about where to find scheduled actions and the separate Pro import scheduler still need their own follow-up.
Please still try
visualizer_schedule_refresh_dbremains missing after Visualizer reactivation #1384 requests this, but PR fix: recover the database refresh chain a killed run ends #1385 does not change documentation.Checks (9 passed)
Ignored PRs: codeinwp/docs-site#2343 (no verifiable link to the issue).
Full report, evidence and session trail
kushh23 commentedon Sep 25, 2026
🧪 Test in Playground
visualizer_schedule_refresh_dbaction, and it stays missing on the next page loads02d9630visualizer_schedule_refresh_dbaction (every 10 minutes) on the first admin page loadSetup: Visualizer's database-refresh action is marked failed, like a run killed mid-flight by the host. Lands on Tools → Scheduled Actions → Pending, filtered to
visualizer_schedule_refresh_db. Tools → QA Logs showsdebug.log.Try: compare the Pending list on both links, then check the Failed tab: both show the one interrupted run.
fix: recover the database refresh chain a killed run ends (#1385)
pirate-bot commentedon Sep 30, 2026
🎉 This issue has been resolved in version 4.0.9 🎉
The release is available on GitHub release
Your semantic-release bot 📦🚀