{"record":{"id":"a2132695bd15700d","repo":"crowdsecurity/crowdsec","slug":"while-starting-flushalerts-scheduler-w","errorCode":null,"errorMessage":"while starting FlushAlerts scheduler: %w","messagePattern":"while starting FlushAlerts scheduler: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/flush.go","lineNumber":64,"sourceCode":"\t\tmaxItems = *config.MaxItems\n\t}\n\n\t// Init & Start cronjob every minute for alerts\n\tscheduler, err := gocron.NewScheduler(\n\t\tgocron.WithLocation(time.UTC),\n\t\tgocron.WithLogger(logging.GoCronLoggerAdapter{Logger: c.Log}),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t_, err = scheduler.NewJob(\n\t\tgocron.DurationJob(1*time.Minute),\n\t\tgocron.NewTask(c.FlushAlerts, ctx, time.Duration(config.MaxAge), maxItems),\n\t\tgocron.WithSingletonMode(gocron.LimitModeReschedule),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"while starting FlushAlerts scheduler: %w\", err)\n\t}\n\n\t// Init & Start cronjob every hour for bouncers/agents\n\tif config.AgentsGC != nil {\n\t\tif config.AgentsGC.Cert != nil {\n\t\t\tduration, err := cstime.ParseDurationWithDays(*config.AgentsGC.Cert)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"while parsing agents cert auto-delete duration: %w\", err)\n\t\t\t}\n\n\t\t\tconfig.AgentsGC.CertDuration = &duration\n\t\t}\n\n\t\tif config.AgentsGC.LoginPassword != nil {\n\t\t\tduration, err := cstime.ParseDurationWithDays(*config.AgentsGC.LoginPassword)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"while parsing agents login/password auto-delete duration: %w\", err)\n\t\t\t}","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/flush.go#L46-L82","documentation":"StartFlushScheduler registers a gocron job that runs FlushAlerts every minute to prune old alerts. This error wraps a failure returned by scheduler.NewJob when the job could not be registered (e.g. invalid scheduling parameters), and it aborts scheduler startup.","triggerScenarios":"scheduler.NewJob returns an error when registering the FlushAlerts task — typically because the scheduler rejects the job definition (nil task function receiver, invalid duration/job options, or scheduler already shut down).","commonSituations":"Calling StartFlushScheduler with a nil or zero-value database Client (c is nil, so gocron.NewTask builds a task it cannot schedule); reusing a scheduler that has been stopped; corrupted gocron options combination.","solutions":["Ensure the database Client (*c) passed to StartFlushScheduler is fully initialized and non-nil before creating the scheduler job.","Check that gocron.NewScheduler succeeded (its error is checked just before) and that the scheduler is not already stopped.","Inspect the wrapped error (%w) for the concrete gocron cause — e.g. invalid job parameters — and fix that input.","If running a custom build, verify gocron v2 options (DurationJob, NewTask, SingletonMode) are constructed exactly as in the source."],"exampleFix":"// before\nc, _ := database.NewClient(cfg) // error ignored, c may be nil\nscheduler, err := c.StartFlushScheduler(ctx, flushCfg)\n\n// after\nc, err := database.NewClient(cfg)\nif err != nil {\n    return err\n}\nscheduler, err := c.StartFlushScheduler(ctx, flushCfg)","handlingStrategy":"try-catch","validationCode":"if c == nil {\n    return errors.New(\"database client must be initialized before StartFlushScheduler\")\n}\nif config == nil {\n    return errors.New(\"flush config must not be nil\")\n}","typeGuard":"if c == nil || c.Ent == nil {\n    return errors.New(\"database client not initialized\")\n}","tryCatchPattern":"scheduler, err := c.StartFlushScheduler(ctx, flushCfg)\nif err != nil {\n    if errors.Is(err, gocron.ErrUpdateJobFuncNotSet) || strings.Contains(err.Error(), \"while starting FlushAlerts scheduler\") {\n        // handle scheduler init failure\n    }\n    return err\n}","preventionTips":["Always construct the database Client via its constructor and check its error before starting the flush scheduler.","Do not reuse or stop the gocron scheduler before jobs are registered.","Log the wrapped error verbatim to expose the gocron cause."],"tags":["go","scheduler","crowdsec","database"],"backgroundTag":"scheduler-job-registration-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}