{"record":{"id":"9a197266df30e3b4","repo":"abpframework/abp","slug":"cannot-convert-period-period-to-cron-expression","errorCode":null,"errorMessage":"Cannot convert period: {period} to cron expression, use HangfireBackgroundWorkerBase to define worker","messagePattern":"Cannot convert period: (.+?) to cron expression, use HangfireBackgroundWorkerBase to define worker","errorType":"exception","errorClass":"AbpException","httpStatus":null,"severity":"error","filePath":"framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs","lineNumber":185,"sourceCode":"        }\n        else if (time.TotalMinutes <= 59)\n        {\n            var minutes = Math.Max(1, (int)Math.Round(time.TotalMinutes));\n            cron = $\"*/{minutes} * * * *\";\n        }\n        else if (time.TotalHours <= 23)\n        {\n            var hours = Math.Max(1, (int)Math.Round(time.TotalHours));\n            cron = $\"0 */{hours} * * *\";\n        }\n        else if(time.TotalDays <= 31)\n        {\n            var days = Math.Max(1, (int)Math.Round(time.TotalDays));\n            cron = $\"0 0 0 1/{days} * *\";\n        }\n        else\n        {\n            throw new AbpException($\"Cannot convert period: {period} to cron expression, use HangfireBackgroundWorkerBase to define worker\");\n        }\n\n        return cron;\n    }\n}\n","sourceCodeStart":167,"sourceCodeEnd":191,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs#L167-L191","documentation":"Thrown by HangfireBackgroundWorkerManager.GetCron when converting a worker's Period (in milliseconds) to a cron expression and the period exceeds 31 days. The converter only supports ranges expressible in standard cron: seconds (<=59s), minutes, hours, and days up to 31. Periods longer than a month cannot be represented because cron has no 'every N months' field in this conversion logic.","triggerScenarios":"Setting an AsyncPeriodicBackgroundWorkerBase or PeriodicBackgroundWorkerBase Period to a value greater than 31 days (2,678,400,000 ms) while using the Hangfire background workers provider. The converter is invoked automatically when the worker is registered with HangfireBackgroundWorkerManager.","commonSituations":"Configuring a monthly or quarterly maintenance worker with Period = TimeSpan.FromDays(60). Setting a Period meant as seconds but accidentally as milliseconds, resulting in an enormous value (e.g. 60,000,000 ms ≈ 16 hours is fine, but 6,000,000,000 exceeds the limit).","solutions":["Reduce the Period to 31 days or less (<= 2,678,400,000 ms).","For periods longer than a month, subclass HangfireBackgroundWorkerBase and set an explicit cron expression directly instead of relying on Period-to-cron conversion.","If the large period was a unit mistake, correct the Period to the intended interval."],"exampleFix":"// before — period exceeds 31 days\npublic class MonthlyReportWorker : AsyncPeriodicBackgroundWorkerBase\n{\n    public MonthlyReportWorker()\n    {\n        Period = (int)TimeSpan.FromDays(45).TotalMilliseconds; // throws\n    }\n}\n\n// after — use HangfireBackgroundWorkerBase with explicit cron\npublic class MonthlyReportWorker : HangfireBackgroundWorkerBase\n{\n    public MonthlyReportWorker()\n    {\n        CronExpression = \"0 0 1 * *\"; // 1st of every month\n    }\n}","handlingStrategy":"validation","validationCode":"int maxPeriodMs = (int)TimeSpan.FromDays(31).TotalMilliseconds;\nif (worker.Period > maxPeriodMs)\n{\n    throw new InvalidOperationException($\"Period {worker.Period} ms exceeds the 31-day cron limit. Use HangfireBackgroundWorkerBase with an explicit CronExpression.\");\n}","typeGuard":"static bool IsCronConvertiblePeriod(int periodMs) => TimeSpan.FromMilliseconds(periodMs).TotalDays <= 31;","tryCatchPattern":null,"preventionTips":["Keep PeriodicBackgroundWorkerBase periods at or below 31 days when using Hangfire.","For monthly+ intervals, subclass HangfireBackgroundWorkerBase and set CronExpression directly.","Centralize worker period constants and validate them against the 31-day ceiling at startup."],"tags":["hangfire","background-workers","cron","scheduling","period-conversion"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}