apache/beam · error
no Extractor fields were set
Error message
no Extractor fields were set
What it means
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.
Source
Thrown at sdks/go/pkg/beam/core/metrics/store.go:111
// DistributionInt64 extracts data from Distribution Int64 counters.
DistributionInt64 func(labels Labels, count, sum, min, max int64)
// GaugeInt64 extracts data from Gauge Int64 counters.
GaugeInt64 func(labels Labels, v int64, t time.Time)
// MsecsInt64 extracts data from StateRegistry of ExecutionState.
// Extraction of Msec counters is experimental and subject to change.
MsecsInt64 func(labels string, e *[4]ExecutionState)
}
// ExtractFrom the given metrics Store all the metrics for
// populated function fields.
// Returns an error if no fields were set.
func (e Extractor) ExtractFrom(store *Store) error {
store.mu.RLock()
defer store.mu.RUnlock()
if e.SumInt64 == nil && e.DistributionInt64 == nil && e.GaugeInt64 == nil {
return fmt.Errorf("no Extractor fields were set")
}
for l, um := range store.store {
switch um.kind() {
case kindSumCounter:
if e.SumInt64 != nil {
data := um.(*counter).get()
e.SumInt64(l, data)
}
case kindDistribution:
if e.DistributionInt64 != nil {
count, sum, min, max := um.(*distribution).get()
e.DistributionInt64(l, count, sum, min, max)
}
case kindGauge:
if e.GaugeInt64 != nil {
v, t := um.(*gauge).get()
e.GaugeInt64(l, v, t)View on GitHub (pinned to 12126d8942)
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.
Example fix
// before
var ex metrics.Extractor
err := ex.ExtractFrom(store)
// after
ex := metrics.Extractor{SumInt64: func(id metrics.MetricName, v int64) { /* ... */ }}
err := ex.ExtractFrom(store) Defensive patterns
Strategy: validation
Validate before calling
if ex.SumInt64 == nil && ex.DistributionInt64 == nil && ex.GaugeInt64 == nil { return errors.New("extractor has no callbacks set") } Type guard
func extractorReady(e metrics.Extractor) bool { return e.SumInt64 != nil || e.DistributionInt64 != nil || e.GaugeInt64 != nil } Try / catch
if err := ex.ExtractFrom(store); err != nil {
if strings.Contains(err.Error(), "no Extractor fields") { return ErrEmptyExtractor }
return err
} Prevention
- Always populate at least one Extractor callback at construction
- Check init branches that conditionally set callbacks
- Skip ExtractFrom entirely when no extraction is intended
When it happens
Trigger: 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.
Common situations: Zero-value Extractor struct passed by mistake; setting callbacks conditionally where the condition never fired; forgetting to wire a custom extraction function during initialization.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Metric namespace must be non-empty
- Metric name must be non-empty
- OnTimer function is defined for the DoFn but no TimerProvide
- empty pipeline
- invalid scope
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d3c8646efeb4520b.
Report an issue: GitHub.