abpframework/abp · error · ArgumentException
At least one of 'Period' or 'CronExpression' must be set.
Error message
At least one of 'Period' or 'CronExpression' must be set.
What it means
Thrown by DynamicBackgroundWorkerSchedule.Validate when neither Period nor CronExpression is set (Period is null and CronExpression is null/whitespace). A dynamic worker must have at least one scheduling directive; with neither, the manager has no way to determine when to run the worker. Validate is called automatically by AddAsync and UpdateScheduleAsync.
Source
Thrown at framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerSchedule.cs:24
{
public const int DefaultPeriod = 60000;
public int? Period { get; set; }
public string? CronExpression { get; set; }
public virtual void Validate()
{
if (Period.HasValue && Period.Value <= 0)
{
throw new ArgumentException(
$"Period must be greater than 0 when provided. Given value: {Period.Value}.",
nameof(Period));
}
if (Period == null && string.IsNullOrWhiteSpace(CronExpression))
{
throw new ArgumentException(
"At least one of 'Period' or 'CronExpression' must be set.");
}
}
}
View on GitHub (pinned to 7ed43b1931)
Solutions
- Set Period to a positive millisecond value (e.g. 60000) on the schedule.
- Set CronExpression to a valid cron string (requires Hangfire/Quartz provider; the default in-memory manager rejects cron).
- Read at least one scheduling value from configuration and ensure it is non-null before constructing the schedule.
Example fix
// before — schedule has neither field set
await manager.AddAsync("worker",
new DynamicBackgroundWorkerSchedule(), handler); // throws
// after — set a period
await manager.AddAsync("worker",
new DynamicBackgroundWorkerSchedule { Period = 60000 }, handler); Defensive patterns
Strategy: validation
Validate before calling
var schedule = new DynamicBackgroundWorkerSchedule();
if (configuredPeriod.HasValue) schedule.Period = configuredPeriod;
else if (!string.IsNullOrWhiteSpace(configuredCron)) schedule.CronExpression = configuredCron;
else throw new InvalidOperationException("Configure either WorkerPeriod or WorkerCron in settings.");
schedule.Validate(); Type guard
static bool HasAtLeastOneSchedule(DynamicBackgroundWorkerSchedule s) => s.Period.HasValue || !string.IsNullOrWhiteSpace(s.CronExpression);
Prevention
- Ensure at least one of Period or CronExpression is explicitly set when constructing the schedule.
- Validate configuration keys exist before building the schedule.
- Use DynamicBackgroundWorkerSchedule.DefaultPeriod as a fallback when configuration is optional.
When it happens
Trigger: Constructing a DynamicBackgroundWorkerSchedule with default values (Period = null, CronExpression = null) and passing it to IDynamicBackgroundWorkerManager.AddAsync or UpdateScheduleAsync. Also thrown on a manual Validate() call on an unconfigured schedule.
Common situations: Building a schedule from optional configuration fields where both Period and CronExpression keys are absent. Intending to set Period but the property name was misspelled or the assignment was lost in a refactor. Passing a schedule object that was constructed but never populated.
Related errors
- Period must be greater than 0 when provided. Given value: {P
- Cannot convert period: {period} to cron expression.
- Cannot convert period: {period} to cron expression, use Hang
- Both 'Period' and 'CronExpression' are not set for {worker.G
- Cannot convert period: {period} to cron expression.
AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13).
Data as JSON: /api/errors/848a37cc40aaff38.
Report an issue: GitHub.