{"record":{"id":"d3c8646efeb4520b","repo":"apache/beam","slug":"no-extractor-fields-were-set","errorCode":null,"errorMessage":"no Extractor fields were set","messagePattern":"no Extractor fields were set","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/metrics/store.go","lineNumber":111,"sourceCode":"\t// DistributionInt64 extracts data from Distribution Int64 counters.\n\tDistributionInt64 func(labels Labels, count, sum, min, max int64)\n\t// GaugeInt64 extracts data from Gauge Int64 counters.\n\tGaugeInt64 func(labels Labels, v int64, t time.Time)\n\n\t// MsecsInt64 extracts data from StateRegistry of ExecutionState.\n\t// Extraction of Msec counters is experimental and subject to change.\n\tMsecsInt64 func(labels string, e *[4]ExecutionState)\n}\n\n// ExtractFrom the given metrics Store all the metrics for\n// populated function fields.\n// Returns an error if no fields were set.\nfunc (e Extractor) ExtractFrom(store *Store) error {\n\tstore.mu.RLock()\n\tdefer store.mu.RUnlock()\n\n\tif e.SumInt64 == nil && e.DistributionInt64 == nil && e.GaugeInt64 == nil {\n\t\treturn fmt.Errorf(\"no Extractor fields were set\")\n\t}\n\n\tfor l, um := range store.store {\n\t\tswitch um.kind() {\n\t\tcase kindSumCounter:\n\t\t\tif e.SumInt64 != nil {\n\t\t\t\tdata := um.(*counter).get()\n\t\t\t\te.SumInt64(l, data)\n\t\t\t}\n\t\tcase kindDistribution:\n\t\t\tif e.DistributionInt64 != nil {\n\t\t\t\tcount, sum, min, max := um.(*distribution).get()\n\t\t\t\te.DistributionInt64(l, count, sum, min, max)\n\t\t\t}\n\t\tcase kindGauge:\n\t\t\tif e.GaugeInt64 != nil {\n\t\t\t\tv, t := um.(*gauge).get()\n\t\t\t\te.GaugeInt64(l, v, t)","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/metrics/store.go#L93-L129","documentation":"metrics.Extractor is a struct of optional extraction callbacks (SumInt64, DistributionInt64, GaugeInt64). ExtractFrom requires at least one callback to be set; if all are nil there is nothing to extract, so it returns this error instead of silently doing nothing. The store is briefly read-locked during the check.","triggerScenarios":"Declaring a metrics.Extractor{} with no fields populated (or only fields for metric kinds not present) and calling ExtractFrom(store), e.g. in dumperExtractor or ResultsExtractor wiring.","commonSituations":"Zero-value Extractor struct passed by mistake; setting callbacks conditionally where the condition never fired; forgetting to wire a custom extraction function during initialization.","solutions":["Set at least one extractor field, e.g. Extractor{SumInt64: func(...) {...}}.","Check initialization logic that populates the Extractor for skipped branches.","If no extraction is intended, skip calling ExtractFrom entirely instead of passing an empty Extractor."],"exampleFix":"// before\nvar ex metrics.Extractor\nerr := ex.ExtractFrom(store)\n// after\nex := metrics.Extractor{SumInt64: func(id metrics.MetricName, v int64) { /* ... */ }}\nerr := ex.ExtractFrom(store)","handlingStrategy":"validation","validationCode":"if ex.SumInt64 == nil && ex.DistributionInt64 == nil && ex.GaugeInt64 == nil { return errors.New(\"extractor has no callbacks set\") }","typeGuard":"func extractorReady(e metrics.Extractor) bool { return e.SumInt64 != nil || e.DistributionInt64 != nil || e.GaugeInt64 != nil }","tryCatchPattern":"if err := ex.ExtractFrom(store); err != nil {\n    if strings.Contains(err.Error(), \"no Extractor fields\") { return ErrEmptyExtractor }\n    return err\n}","preventionTips":["Always populate at least one Extractor callback at construction","Check init branches that conditionally set callbacks","Skip ExtractFrom entirely when no extraction is intended"],"tags":["go","apache-beam","metrics","validation"],"backgroundTag":"empty-required-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}