apache/beam · error

CreateTracker has unexpected number of return values: %v

Error message

CreateTracker has unexpected number of return values: %v

What it means

The SDF invoker requires CreateTracker to return either 1 value (an sdf.RTracker) or 2 values (RTracker + error). Other return counts cannot be dispatched and panic. Additionally the first return value must implement sdf.RTracker, since the generated code type-asserts it.

Source

Thrown at sdks/go/pkg/beam/core/runtime/exec/sdf_invokers_arity.tmpl:197

	{{end}}
{{end}}
{{end}}
	default:
		if len(n.fn.Param) < 1 || len(n.fn.Param) > 2 {
			return errors.Errorf("CreateTracker has unexpected number of parameters: %v", len(n.fn.Param))
		}

		n.call = func() (rt sdf.RTracker, err error) {
			ret := n.fn.Fn.Call(n.args)

			switch len(ret) {
			case 1:
				return ret[0].(sdf.RTracker), nil
			case 2:
				return ret[0].(sdf.RTracker), asError(ret[1])
			}

			panic(fmt.Sprintf("CreateTracker has unexpected number of return values: %v", len(ret)))
		}
	}

	return nil
}

func (n *trInvoker) initCallFn() error {
	// Expects a signature of the form:
	// (context.Context?, sdf.RTracker, key?, value) (restriction, error?)
	// TODO(BEAM-9643): Link to full documentation.
	switch fnT := n.fn.Fn.(type) {
{{range $out := upto 3}}
{{range $in := upto 5}}
    {{if gt $out 0}}
    {{if gt $in 1}}
	case reflectx.Func{{$in}}x{{$out}}:
		n.call = func() (rest any, err error) {
			{{mktuplef $out "r%v"}} := fnT.Call{{$in}}x{{$out}}({{mktuplef $in "n.args[%v]"}})

View on GitHub (pinned to 12126d8942)

Solutions

  1. Make CreateTracker return exactly (sdf.RTracker) or (sdf.RTracker, error)
  2. Ensure the returned type implements sdf.RTracker (TryClaim, TrySplit, GetProgress, IsDone, etc.)
  3. Compare against the Beam Go SDF examples to confirm the full method set

Example fix

// before
func (fn *sdfFn) CreateTracker(r Rest) (MyTracker, bool) { ... }

// after
func (fn *sdfFn) CreateTracker(r Rest) (sdf.RTracker, error) {
    return &myTracker{r: r}, nil
}
Defensive patterns

Strategy: validation

Validate before calling

m := reflect.ValueOf(fn).MethodByName("CreateTracker")
if m.IsValid() {
    t := m.Type()
    if (t.NumOut() != 1 && t.NumOut() != 2) || !t.Out(0).Implements(reflect.TypeOf((*sdf.RTracker)(nil)).Elem()) {
        return fmt.Errorf("CreateTracker must return sdf.RTracker (plus optional error)")
    }
}

Type guard

func validCreateTracker(fn interface{}) bool {
    m := reflect.ValueOf(fn).MethodByName("CreateTracker")
    if !m.IsValid() { return false }
    t := m.Type()
    rt := reflect.TypeOf((*sdf.RTracker)(nil)).Elem()
    return (t.NumOut() == 1 || t.NumOut() == 2) && t.Out(0).Implements(rt)
}

Try / catch

defer func() {
    if r := recover(); strings.Contains(fmt.Sprint(r), "CreateTracker has unexpected number of return values") {
        log.Fatalf("SDF signature error: %v", r)
    }
}()

Prevention

When it happens

Trigger: A splittable DoFn whose CreateTracker returns 0 or 3+ values, or whose first return does not implement sdf.RTracker, executed in a pipeline.

Common situations: Returning a custom restriction tracker type that doesn't implement the sdf.RTracker interface; wrong return arity from refactoring.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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