{"record":{"id":"923880d38ab7ee78","repo":"hibiken/asynq","slug":"initial-call-to-getconfigs-contained-an-invalid-co","errorCode":null,"errorMessage":"initial call to GetConfigs contained an invalid config: %w","messagePattern":"initial call to GetConfigs contained an invalid config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"periodic_task_manager.go","lineNumber":175,"sourceCode":"// Once it receives a signal, it gracefully shuts down the manager.\nfunc (mgr *PeriodicTaskManager) Run() error {\n\tif err := mgr.Start(); err != nil {\n\t\treturn err\n\t}\n\tmgr.s.waitForSignals()\n\tmgr.Shutdown()\n\tmgr.s.logger.Debugf(\"PeriodicTaskManager exiting\")\n\treturn nil\n}\n\nfunc (mgr *PeriodicTaskManager) initialSync() error {\n\tconfigs, err := mgr.p.GetConfigs()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"initial call to GetConfigs failed: %w\", err)\n\t}\n\tfor _, c := range configs {\n\t\tif err := validatePeriodicTaskConfig(c); err != nil {\n\t\t\treturn fmt.Errorf(\"initial call to GetConfigs contained an invalid config: %w\", err)\n\t\t}\n\t}\n\tmgr.add(configs)\n\treturn nil\n}\n\nfunc (mgr *PeriodicTaskManager) add(configs []*PeriodicTaskConfig) {\n\tfor _, c := range configs {\n\t\tentryID, err := mgr.s.Register(c.Cronspec, c.Task, c.Opts...)\n\t\tif err != nil {\n\t\t\tmgr.s.logger.Errorf(\"Failed to register periodic task: cronspec=%q task=%q err=%v\",\n\t\t\t\tc.Cronspec, c.Task.Type(), err)\n\t\t\tcontinue\n\t\t}\n\t\tmgr.m[c.hash()] = entryID\n\t\tmgr.s.logger.Infof(\"Successfully registered periodic task: cronspec=%q task=%q, entryID=%s\",\n\t\t\tc.Cronspec, c.Task.Type(), entryID)\n\t}","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/hibiken/asynq/blob/d135f1439bee74e989b7f9b41ecd542cc87f024a/periodic_task_manager.go#L157-L193","documentation":"initialSync validates every config returned by GetConfigs; this error means one of them failed validation (nil config, nil Task, empty Cronspec, or duplicate EntryID). The whole sync aborts rather than partially registering configs, so the manager fails to start.","triggerScenarios":"Provider's GetConfigs returned a list where at least one PeriodicTaskConfig is invalid: config==nil, config.Task==nil, Cronspec==\"\", or a repeated EntryID.","commonSituations":"A newly added entry in the config store has a typo'd/empty cron field; two entries accidentally share an ID after copy-paste; provider code appends a zero-value config on error paths.","solutions":["Log/iterate provider configs locally and run the same validation to find the offending entry","Fix the invalid entry (set Task and Cronspec, assign a unique EntryID)","Make the provider skip or sanitize invalid entries before returning them"],"exampleFix":"// before\nconfigs := append(cfgs, &PeriodicTaskConfig{}) // zero value\n// after\nconfigs := append(cfgs, NewPeriodicTaskConfig(task, \"*/10 * * * *\"))","handlingStrategy":"validation","validationCode":"for _, c := range configs {\n    if c == nil || c.Task == nil || c.Cronspec == \"\" {\n        return errors.New(\"provider returned an invalid periodic task config\")\n    }\n}\nids := map[string]bool{}\nfor _, c := range configs {\n    if ids[c.EntryID] { return fmt.Errorf(\"duplicate EntryID %q\", c.EntryID) }\n    ids[c.EntryID] = true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate provider output in a unit test mirroring asynq's rules (non-nil, Task non-nil, Cronspec non-empty, unique EntryID)","Sanitize or skip invalid rows in the provider before returning","Use migrations/constraints to prevent blank cron fields in the config store"],"tags":["asynq","validation","config-provider"],"backgroundTag":"schema-validation-failed","analyzedSha":"d135f1439bee74e989b7f9b41ecd542cc87f024a","analyzedAt":"2026-09-07T19:02:34.660Z","contentChangedAt":"2026-09-07T19:02:34.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}