hibiken/asynq · error
PeriodicTaskConfigProvider cannot be nil
Error message
PeriodicTaskConfigProvider cannot be nil
What it means
NewPeriodicTaskManager validates its options before constructing the manager and returns this error when PeriodicTaskConfigProvider is nil. The provider is the callback that supplies the list of periodic task configs during sync, so the manager cannot function without it. This fails fast at construction time.
Solutions
- Set PeriodicTaskConfigProvider to a function returning ([]*PeriodicTaskConfig, error)
- Double-check the PeriodicTaskManagerOpts literal includes the provider
- Add a unit test constructing the manager with production opts
Example fix
// before
mgr, err := asynq.NewPeriodicTaskManager(asynq.PeriodicTaskManagerOpts{
RedisConnOpt: asynq.RedisClientOpt{Addr: redisAddr},
})
// after
mgr, err := asynq.NewPeriodicTaskManager(asynq.PeriodicTaskManagerOpts{
RedisConnOpt: asynq.RedisClientOpt{Addr: redisAddr},
PeriodicTaskConfigProvider: getPeriodicConfigs,
}) Defensive patterns
Strategy: validation
Validate before calling
if opts.PeriodicTaskConfigProvider == nil {
return errors.New("PeriodicTaskConfigProvider must be set")
}
mgr, err := asynq.NewPeriodicTaskManager(opts) Try / catch
mgr, err := asynq.NewPeriodicTaskManager(opts)
if err != nil {
log.Fatalf("invalid periodic task manager opts: %v", err)
} Prevention
- Always set PeriodicTaskConfigProvider in PeriodicTaskManagerOpts
- Build opts in one reviewed constructor function
- Add a constructor smoke test to CI
- Enable linters flagging zero-value struct literals
When it happens
Trigger: Calling NewPeriodicTaskManager(PeriodicTaskManagerOpts{}) or omitting the PeriodicTaskConfigProvider field while setting RedisConnOpt/SchedulerOpts.
Common situations: Copy-pasting an example and dropping the provider field; building opts dynamically where the provider assignment is skipped; refactoring that renamed the field.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- RedisConnOpt/RedisUniversalClient cannot be nil
- PeriodicTaskConfig cannot be nil
- PeriodicTaskConfig.Task cannot be nil
- task ID cannot be empty
- Unique TTL cannot be less than 1s
AI-assisted analysis of hibiken/asynq@d135f1439b (2026-09-07).
Data as JSON: /api/errors/dd7d6ed55f0fcaf4.
Report an issue: GitHub.
Appendix: source
Thrown at periodic_task_manager.go:51
RedisConnOpt RedisConnOpt
// Optional: if RedisUniversalClient is non nil, RedisConnOpt is ignored.
RedisUniversalClient redis.UniversalClient
// Optional: scheduler options
*SchedulerOpts
// Optional: default is 3m
SyncInterval time.Duration
}
const defaultSyncInterval = 3 * time.Minute
// NewPeriodicTaskManager returns a new PeriodicTaskManager instance.
// The given opts should specify the RedisConnOp and PeriodicTaskConfigProvider at minimum.
func NewPeriodicTaskManager(opts PeriodicTaskManagerOpts) (*PeriodicTaskManager, error) {
if opts.PeriodicTaskConfigProvider == nil {
return nil, fmt.Errorf("PeriodicTaskConfigProvider cannot be nil")
}
if opts.RedisConnOpt == nil && opts.RedisUniversalClient == nil {
return nil, fmt.Errorf("RedisConnOpt/RedisUniversalClient cannot be nil")
}
var scheduler *Scheduler
if opts.RedisUniversalClient != nil {
scheduler = NewSchedulerFromRedisClient(opts.RedisUniversalClient, opts.SchedulerOpts)
} else {
scheduler = NewScheduler(opts.RedisConnOpt, opts.SchedulerOpts)
}
syncInterval := opts.SyncInterval
if syncInterval == 0 {
syncInterval = defaultSyncInterval
}
return &PeriodicTaskManager{
s: scheduler,
p: opts.PeriodicTaskConfigProvider,View on GitHub (pinned to d135f1439b)