{"record":{"id":"147cd4b63f243670","repo":"jaegertracing/jaeger","slug":"calculationinterval-and-aggregationbuckets-must-be","errorCode":null,"errorMessage":"CalculationInterval and AggregationBuckets must be greater than 0","messagePattern":"CalculationInterval and AggregationBuckets must be greater than 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sampling/samplingstrategy/adaptive/post_aggregator.go","lineNumber":32,"sourceCode":"\n\t\"github.com/jaegertracing/jaeger/internal/leaderelection\"\n\t\"github.com/jaegertracing/jaeger/internal/metrics\"\n\t\"github.com/jaegertracing/jaeger/internal/sampling/samplingstrategy/adaptive/calculationstrategy\"\n\t\"github.com/jaegertracing/jaeger/internal/storage/v1/api/samplingstore\"\n\t\"github.com/jaegertracing/jaeger/internal/storage/v1/api/samplingstore/model\"\n)\n\nconst (\n\tmaxSamplingProbability = 1.0\n\n\tgetThroughputErrMsg = \"failed to get throughput from storage\"\n\n\t// The number of past entries for samplingCache the leader keeps in memory\n\tserviceCacheSize = 25\n)\n\nvar (\n\terrNonZero               = errors.New(\"CalculationInterval and AggregationBuckets must be greater than 0\")\n\terrBucketsForCalculation = errors.New(\"BucketsForCalculation cannot be less than 1\")\n)\n\n// nested map: service -> operation -> throughput.\ntype serviceOperationThroughput map[string]map[string]*model.Throughput\n\nfunc (t serviceOperationThroughput) get(service, operation string) (*model.Throughput, bool) {\n\tsvcThroughput, ok := t[service]\n\tif ok {\n\t\tv, ok := svcThroughput[operation]\n\t\treturn v, ok\n\t}\n\treturn nil, false\n}\n\n// nested map: service -> operation -> buckets of QPS values.\ntype serviceOperationQPS map[string]map[string][]float64\n","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/sampling/samplingstrategy/adaptive/post_aggregator.go#L14-L50","documentation":"errNonZero is returned by newPostAggregator in the adaptive sampling strategy when its Configuration has a zero or negative CalculationInterval or AggregationBuckets. Both values drive the periodic post-aggregation loop, so they must be strictly positive for the aggregator to function.","triggerScenarios":"Starting the adaptive sampling leader/aggregator with a Configuration where CalculationInterval <= 0 or AggregationBuckets <= 0 (e.g. unset interval in the adaptive sampling config).","commonSituations":"Building a custom config struct in Go without setting these fields; YAML/env config omitting the values; copying a minimal config that only sets a few options.","solutions":["Set CalculationInterval to a positive duration (e.g. 10s).","Set AggregationBuckets to a positive integer (e.g. 10).","Use the provided default/flag-driven configuration rather than hand-building the struct so defaults apply."],"exampleFix":"// before\nconf := &sampling.Config{}\nagg := sampling.NewAggregator(conf) // error\n// after\nconf := &sampling.Config{CalculationInterval: 10 * time.Second, AggregationBuckets: 10}\nagg := sampling.NewAggregator(conf) // ok","handlingStrategy":"validation","validationCode":"if cfg.CalculationInterval <= 0 || cfg.AggregationBuckets <= 0 {\n    return errors.New(\"CalculationInterval and AggregationBuckets must be greater than 0\")\n}","typeGuard":null,"tryCatchPattern":"agg, err := sampling.NewAggregator(cfg)\nif err != nil {\n    logger.Fatal(\"invalid adaptive sampling config\", zap.Error(err))\n}","preventionTips":["Set positive CalculationInterval and AggregationBuckets explicitly.","Prefer flag/env-driven defaults over hand-built structs.","Fail fast at startup by validating config before launching."],"tags":["config","sampling","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}