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

  1. Set at least one extractor field, e.g. Extractor{SumInt64: func(...) {...}}.
  2. Check initialization logic that populates the Extractor for skipped branches.
  3. 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

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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/d3c8646efeb4520b. Report an issue: GitHub.