{"record":{"id":"0d947abcbc70fe0a","repo":"jaegertracing/jaeger","slug":"field-s-buckets-should-only-be-defined-for-tim","errorCode":null,"errorMessage":"Field [%s]: Buckets should only be defined for Timer and Histogram metric types","messagePattern":"Field \\[(.+?)\\]: Buckets should only be defined for Timer and Histogram metric types","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/metrics/metrics.go","lineNumber":96,"sourceCode":"\t\t\t\t\t\t\tfield.Name, bucket, bucketString,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\ttimerBuckets = append(timerBuckets, d)\n\t\t\t\t}\n\t\t\tcase field.Type.AssignableTo(histogramPtrType):\n\t\t\t\tbucketValues := strings.Split(bucketString, \",\")\n\t\t\t\tfor _, bucket := range bucketValues {\n\t\t\t\t\tb, err := strconv.ParseFloat(bucket, 64)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\t\t\"Field [%s]: Bucket [%s] could not be converted to float64 in 'buckets' string [%s]\",\n\t\t\t\t\t\t\tfield.Name, bucket, bucketString,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\thistogramBuckets = append(histogramBuckets, b)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"Field [%s]: Buckets should only be defined for Timer and Histogram metric types\",\n\t\t\t\t\tfield.Name,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\thelp := field.Tag.Get(\"help\")\n\t\tvar obj any\n\t\tswitch {\n\t\tcase field.Type.AssignableTo(counterPtrType):\n\t\t\tobj = factory.Counter(Options{\n\t\t\t\tName: metric,\n\t\t\t\tTags: tags,\n\t\t\t\tHelp: help,\n\t\t\t})\n\t\tcase field.Type.AssignableTo(gaugePtrType):\n\t\t\tobj = factory.Gauge(Options{\n\t\t\t\tName: metric,\n\t\t\t\tTags: tags,","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/metrics/metrics.go#L78-L114","documentation":"metrics.Init() only applies a `buckets` tag to *Timer and *Histogram fields; for any other metric type (Counter, Gauge, etc.) the presence of a buckets tag is a configuration mistake and returns this error naming the field. Buckets have no meaning for counters and gauges, so the library refuses rather than ignoring them.","triggerScenarios":"A *Counter or *Gauge (or any non-timer/histogram field) declaring `buckets:\"...\"` in its struct tag when Init/MustInit runs.","commonSituations":"Copy-pasting a full tag line from a timer/histogram field onto a counter; converting a Histogram field to a Counter without removing its buckets tag.","solutions":["Remove the buckets tag from the offending non-timer/histogram field","If buckets are needed, change the field type to *Timer or *Histogram","Double-check the field's pointer type matches the intended metric kind"],"exampleFix":"// before\nTotal *Counter `metric:\"total\" buckets:\"1,2,3\"`\n// after\nTotal *Counter `metric:\"total\"`","handlingStrategy":"validation","validationCode":"func bucketsAllowed(t reflect.Type) bool {\n    return reflect.PointerTo(timerType) == t || reflect.PointerTo(histogramType) == t\n}","typeGuard":null,"tryCatchPattern":"if err := metrics.Init(&m); err != nil {\n    if strings.Contains(err.Error(), \"only be defined for Timer and Histogram\") {\n        // drop the buckets tag or change the field type\n    }\n    return err\n}","preventionTips":["Only add buckets tags to *Timer and *Histogram fields","Remove buckets when converting a histogram/timer to counter/gauge","Review full tag lines when copy-pasting between metric kinds","Add a test that Initializes every metrics struct in the codebase"],"tags":["reflection","struct-tags","metrics"],"backgroundTag":"invalid-bucket-spec","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}