{"record":{"id":"567b8d939c8fc0bd","repo":"crowdsecurity/crowdsec","slug":"while-starting-flushmetrics-scheduler-w","errorCode":null,"errorMessage":"while starting flushMetrics scheduler: %w","messagePattern":"while starting flushMetrics scheduler: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/flush.go","lineNumber":131,"sourceCode":"\t\t}\n\t}\n\n\t_, err = scheduler.NewJob(\n\t\tgocron.DurationJob(flushInterval),\n\t\tgocron.NewTask(c.FlushAgentsAndBouncers, ctx, config.AgentsGC, config.BouncersGC),\n\t\tgocron.WithSingletonMode(gocron.LimitModeReschedule),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"while starting FlushAgentsAndBouncers scheduler: %w\", err)\n\t}\n\n\t_, err = scheduler.NewJob(\n\t\tgocron.DurationJob(flushInterval),\n\t\tgocron.NewTask(c.flushMetrics, ctx, time.Duration(config.MetricsMaxAge)),\n\t\tgocron.WithSingletonMode(gocron.LimitModeReschedule),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"while starting flushMetrics scheduler: %w\", err)\n\t}\n\n\t_, err = scheduler.NewJob(\n\t\tgocron.DurationJob(flushInterval),\n\t\tgocron.NewTask(c.flushAllowlists, ctx),\n\t\tgocron.WithSingletonMode(gocron.LimitModeReschedule),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"while starting FlushAllowlists scheduler: %w\", err)\n\t}\n\n\tscheduler.Start()\n\n\treturn scheduler, nil\n}\n\n// flushMetrics deletes metrics older than maxAge, regardless if they have been pushed to CAPI or not\nfunc (c *Client) flushMetrics(ctx context.Context, maxAge time.Duration) {","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/flush.go#L113-L149","documentation":"StartFlushScheduler registers a gocron job that runs flushMetrics every minute, deleting metrics older than metrics_max_age. This error wraps a scheduler.NewJob registration failure and aborts startup.","triggerScenarios":"scheduler.NewJob fails when registering the flushMetrics task — invalid task construction, scheduler in an invalid state, or gocron rejecting the job definition.","commonSituations":"Nil database Client making the method value unusable; time.Duration(config.MetricsMaxAge) computed from a config typo in a custom build; gocron option misuse.","solutions":["Ensure the Client is non-nil and fully initialized.","Inspect the wrapped error for the gocron-level cause and correct that input.","Confirm earlier jobs in StartFlushScheduler did not leave the scheduler in a bad state.","Check config.MetricsMaxAge resolves to a sane (non-negative) duration."],"exampleFix":"// before\nscheduler, err := c.StartFlushScheduler(ctx, nil)\n\n// after\nif flushCfg == nil {\n    flushCfg = csconfig.DefaultFlushDBCfg()\n}\nscheduler, err := c.StartFlushScheduler(ctx, flushCfg)","handlingStrategy":"try-catch","validationCode":"if config != nil && config.MetricsMaxAge < 0 {\n    return errors.New(\"metrics_max_age must not be negative\")\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 strings.Contains(err.Error(), \"flushMetrics scheduler\") {\n        // scheduler registration failed\n    }\n    return err\n}","preventionTips":["Verify metrics_max_age is a valid non-negative duration in config.","Initialize the DB client before scheduler startup.","Treat any wrapped gocron error as fatal at startup, not recoverable mid-run."],"tags":["go","scheduler","crowdsec","metrics"],"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-14T00:17:10.932Z"}