{"record":{"id":"7a8446d179509bf2","repo":"jaegertracing/jaeger","slug":"field-s-tag-s-is-not-of-the-form-key-value","errorCode":null,"errorMessage":"Field [%s]: Tag [%s] is not of the form key=value in 'tags' string [%s]","messagePattern":"Field \\[(.+?)\\]: Tag \\[(.+?)\\] is not of the form key=value in 'tags' string \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/metrics/metrics.go","lineNumber":61,"sourceCode":"\thistogramPtrType := reflect.TypeFor[Histogram]()\n\n\tv := reflect.ValueOf(m).Elem()\n\tt := v.Type()\n\tfor i := 0; i < t.NumField(); i++ {\n\t\ttags := make(map[string]string)\n\t\tmaps.Copy(tags, globalTags)\n\t\tvar histogramBuckets []float64\n\t\tvar timerBuckets []time.Duration\n\t\tfield := t.Field(i)\n\t\tmetric := field.Tag.Get(\"metric\")\n\t\tif metric == \"\" {\n\t\t\treturn fmt.Errorf(\"Field %s is missing a tag 'metric'\", field.Name)\n\t\t}\n\t\tif tagString := field.Tag.Get(\"tags\"); tagString != \"\" {\n\t\t\tfor tagPair := range strings.SplitSeq(tagString, \",\") {\n\t\t\t\ttag := strings.Split(tagPair, \"=\")\n\t\t\t\tif len(tag) != 2 {\n\t\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\t\"Field [%s]: Tag [%s] is not of the form key=value in 'tags' string [%s]\",\n\t\t\t\t\t\tfield.Name, tagPair, tagString,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\ttags[tag[0]] = tag[1]\n\t\t\t}\n\t\t}\n\t\tif bucketString := field.Tag.Get(\"buckets\"); bucketString != \"\" {\n\t\t\tswitch {\n\t\t\tcase field.Type.AssignableTo(timerPtrType):\n\t\t\t\tbucketValues := strings.Split(bucketString, \",\")\n\t\t\t\tfor _, bucket := range bucketValues {\n\t\t\t\t\td, err := time.ParseDuration(bucket)\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 parsed as duration in 'buckets' string [%s]\",\n\t\t\t\t\t\t\tfield.Name, bucket, bucketString,\n\t\t\t\t\t\t)","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/metrics/metrics.go#L43-L79","documentation":"metrics.Init() parses the `tags` struct tag as a comma-separated list of key=value pairs. If any pair in the tag string splits on '=' into something other than exactly two parts, Init returns this error naming the field, the offending pair, and the full tags string.","triggerScenarios":"A field's `tags:\"...\"` value containing a pair without '=' or with multiple '=' (e.g. `tags:\"service,env=prod\"` or `tags:\"a=b=c\"`) when Init/MustInit runs.","commonSituations":"Hand-writing tag lists and forgetting a '=value'; putting commas in a tag value without quoting/escaping; typos like `tags:\"env prod\"`.","solutions":["Fix the named tag pair to be exactly key=value","Remove empty/extra pairs from the tags string (no stray or trailing commas)","Escape or avoid '=' inside tag values","Verify every comma-separated segment has exactly one '='"],"exampleFix":"// before\nRequests *Counter `metric:\"requests\" tags:\"service,\"`\n// after\nRequests *Counter `metric:\"requests\" tags:\"service=jaeger-query\"`","handlingStrategy":"validation","validationCode":"func checkTagsTag(s string) error {\n    for _, pair := range strings.Split(s, \",\") {\n        if len(strings.Split(pair, \"=\")) != 2 {\n            return fmt.Errorf(\"bad tag pair %q in %q\", pair, s)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := metrics.Init(&m); err != nil {\n    if strings.Contains(err.Error(), \"not of the form key=value\") {\n        // correct the tags string reported in the error\n    }\n    return err\n}","preventionTips":["Keep tag values free of '=' and ',' or restructure them","Format tags strictly as key1=v1,key2=v2","Lint struct tags with a tool (e.g. golangci-lint structcheck/tagliatelle)","Count '=' per pair when hand-writing tags"],"tags":["reflection","struct-tags","metrics"],"backgroundTag":"malformed-struct-tag","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}