{"data":{"id":"magento2-38693","source":"github-pr","sourceRef":"magento/magento2#38693","title":"Cleanup of cron_schedule database table doesn't cleanup non-existing jobs","pr":{"number":38693,"url":"https://github.com/magento/magento2/pull/38693","author":"fredden","mergedAt":"2024-07-04T16:37:36Z","mergeCommit":"8ff1c16409cddf8b67ba40b767779d6149670e0d","headCommit":"9ebddc600c0a9828981626e86a03ca813b587305","baseRef":"2.4-develop","diffSha256":"2b1639c0c27c63c9a91b3334467d3afb8b656976de51486e2b9b5f31fe18ab8c"},"issues":[{"number":38217,"url":"https://github.com/magento/magento2/issues/38217","title":"Cleanup of cron_schedule database table doesn't cleanup non-existing jobs","labels":["Area: Catalog","Component: Cron","Issue: Confirmed","Priority: P2","Progress: done","Reported on 2.4.6-p3","Reproduced on 2.4.x"],"kind":"human"}],"fixedIn":"2.4.8","containingTags":["2.4.8","2.4.8-p1","2.4.8-p2","2.4.8-p3","2.4.8-p4","2.4.8-p5","2.4.9"],"reportedOn":"2.4.6-p3","codeMatch":{"2.4.6":"conflict","2.4.6-p1":"conflict","2.4.6-p2":"conflict","2.4.6-p3":"conflict","2.4.6-p4":"conflict","2.4.6-p5":"conflict","2.4.6-p6":"conflict","2.4.6-p7":"conflict","2.4.6-p8":"conflict","2.4.6-p9":"conflict","2.4.6-p10":"conflict","2.4.6-p11":"conflict","2.4.6-p12":"conflict","2.4.6-p13":"conflict","2.4.6-p14":"conflict","2.4.6-p15":"conflict","2.4.7":"conflict","2.4.7-p1":"conflict","2.4.7-p2":"conflict","2.4.7-p3":"conflict","2.4.7-p4":"conflict","2.4.7-p5":"conflict","2.4.7-p6":"conflict","2.4.7-p7":"conflict","2.4.7-p8":"conflict","2.4.7-p9":"conflict","2.4.7-p10":"conflict","2.4.8":"conflict","2.4.8-p1":"conflict","2.4.8-p2":"conflict","2.4.8-p3":"conflict","2.4.8-p4":"conflict","2.4.8-p5":"conflict","2.4.9":"conflict"},"affectedVersions":[],"components":["magento/module-cron"],"files":[{"path":"app/code/Magento/Cron/Cron/CleanOldJobs.php","change":"added","package":"magento/module-cron"},{"path":"app/code/Magento/Cron/composer.json","change":"modified","package":"magento/module-cron"},{"path":"app/code/Magento/Cron/etc/crontab.xml","change":"added","package":"magento/module-cron"},{"path":"app/code/Magento/Cron/etc/module.xml","change":"modified","package":"magento/module-cron"}],"stripped":{"tests":["app/code/Magento/Cron/Test/Unit/Cron/CleanOldJobsTest.php"],"docs":[],"outsideCode":[]},"linesChanged":111,"mergeBatched":false,"excluded":null,"sections":{"description":"See that there are still jobs `inventory_in_store_pickup_sales_send_order_notified_emails` in the table with status success and being older then 60 minutes. Those don't get cleaned up because the MSI modules are no longer active and calling `getJobs()` [over here](https://github.com/magento/magento2/blob/2.4.6-p3/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php#L577) doesn't return jobs from inactive (or removed) modules.","stepsToReproduce":"Explanation below how to trigger this with a cronjob from inside core Magento. But the most likely cases will come from 3rd party modules containing cronjobs, that were installed for a while and then removed again.\n\n1. Have a Magento shop with MSI modules enabled\n2. Have a working crontab and have it running for a couple of hours\n3. Inspect the `cron_schedule` table and notice that the job `inventory_in_store_pickup_sales_send_order_notified_emails` is mentioned many times with status `success`\n4. Now, disable all MSI modules in `app/etc/config.php` and run `bin/magento setup:upgrade`\n5. Keep the crontab running for a few more hours\n6. Inspect your `cron_schedule` table again","expectedResult":"It's expected that all jobs that were successful and having run more than 60 minutes ago are removed from the `cron_schedule` table.","actualResult":"See that there are still jobs `inventory_in_store_pickup_sales_send_order_notified_emails` in the table with status success and being older then 60 minutes. Those don't get cleaned up because the MSI modules are no longer active and calling `getJobs()` [over here](https://github.com/magento/magento2/blob/2.4.6-p3/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php#L577) doesn't return jobs from inactive (or removed) modules.","source":"issue"},"signatures":[],"labels":{"area":["Catalog"],"component":["Cron"],"priority":"P2","severity":null,"reportedOn":["2.4.6-p3"]},"categories":["Cron"],"triage":{"model":"@cf/cloudflare/clef","requestHash":"4d6916c3615d95625c27aebd467bb4d06132eb905fc011db3181fc18daf1389f","isBugfix":0.8996,"changeKind":{"choice":"bugfix","probabilities":{"bugfix":0.7889,"feature":0.1623,"refactor":0.0255,"tests_only":0.0102,"docs_only":0.0053,"dependency":0.0078},"confidence":0.5794},"scope":{"score":1.0377,"probabilities":{"0":0.2568,"1":0.4486,"2":0.2946},"confidence":0.031},"risk":{"score":0.3165,"probabilities":{"0":0.7581,"1":0.1674,"2":0.0745},"confidence":0.4124},"area":{"choice":"framework","probabilities":{"catalog":0.0145,"checkout":0.0054,"customer":0.0042,"admin":0.0109,"graphql_api":0.0034,"framework":0.9454,"frontend":0.005,"other":0.0112},"confidence":0.8793},"securityRelevant":0.0065,"reportedVersion":{"choice":"2.4.6-p3","probabilities":{"2.4.0":0.0021,"2.4.0-p1":0.0024,"2.4.1":0.0022,"2.4.1-p1":0.0024,"2.4.2":0.0024,"2.4.2-p1":0.0026,"2.4.2-p2":0.0029,"2.4.3":0.0031,"2.4.3-p1":0.0033,"2.4.3-p2":0.004,"2.4.3-p3":0.004,"2.4.4":0.0028,"2.4.4-p1":0.003,"2.4.4-p10":0.0038,"2.4.4-p11":0.0052,"2.4.4-p12":0.0046,"2.4.4-p13":0.0052,"2.4.4-p14":0.0048,"2.4.4-p15":0.0036,"2.4.4-p16":0.0044,"2.4.4-p17":0.0035,"2.4.4-p18":0.0029,"2.4.4-p2":0.0027,"2.4.4-p3":0.0025,"2.4.4-p4":0.0028,"2.4.4-p5":0.0033,"2.4.4-p6":0.0043,"2.4.4-p7":0.0038,"2.4.4-p8":0.0041,"2.4.4-p9":0.003,"2.4.5":0.0042,"2.4.5-p1":0.0035,"2.4.5-p10":0.0033,"2.4.5-p11":0.0039,"2.4.5-p12":0.0051,"2.4.5-p13":0.0045,"2.4.5-p14":0.0043,"2.4.5-p15":0.0036,"2.4.5-p16":0.0036,"2.4.5-p17":0.0031,"2.4.5-p2":0.0031,"2.4.5-p3":0.0036,"2.4.5-p4":0.0034,"2.4.5-p5":0.0031,"2.4.5-p6":0.0051,"2.4.5-p7":0.0037,"2.4.5-p8":0.0037,"2.4.5-p9":0.0026,"2.4.6":0.0313,"2.4.6-p1":0.004,"2.4.6-p10":0.0031,"2.4.6-p11":0.0034,"2.4.6-p12":0.0031,"2.4.6-p13":0.0083,"2.4.6-p14":0.0036,"2.4.6-p15":0.0048,"2.4.6-p2":0.0093,"2.4.6-p3":0.6344,"2.4.6-p4":0.0109,"2.4.6-p5":0.008,"2.4.6-p6":0.0098,"2.4.6-p7":0.0066,"2.4.6-p8":0.0055,"2.4.6-p9":0.0047,"2.4.7":0.0052,"2.4.7-p1":0.0038,"2.4.7-p10":0.004,"2.4.7-p2":0.0033,"2.4.7-p3":0.0044,"2.4.7-p4":0.0046,"2.4.7-p5":0.004,"2.4.7-p6":0.0045,"2.4.7-p7":0.0036,"2.4.7-p8":0.0036,"2.4.7-p9":0.0027,"2.4.8":0.0038,"2.4.8-p1":0.0044,"2.4.8-p2":0.0051,"2.4.8-p3":0.0051,"2.4.8-p4":0.0054,"2.4.8-p5":0.0049,"2.4.9":0.0039,"unspecified":0.0038},"confidence":0.3977},"backportWorthy":{"score":1.364,"probabilities":{"0":0.1707,"1":0.2945,"2":0.5348},"confidence":0.1028}},"curated":{"title":"Fixes cron_schedule keeping entries for jobs that no longer exist","description":"Entries for cron jobs which no longer exist, such as when a module is removed, stay in the cron_schedule table because getJobs() doesn't return jobs from inactive or removed modules. A new daily clean_cron_schedule job (CleanOldJobs) will delete every cron_schedule row with scheduled_at older than the max history success or failure value plus one day, for all jobs.","categories":["Cron"],"author":"claude-code/opus-5.5","date":"2026-10-06","reviewedBy":null},"tests":null},"_documentation":"https://magento.watch/api","_description":"Upstream fix magento2-38693 details"}