apache/beam · error

SplitRestriction has unexpected number of return values: %v

Error message

SplitRestriction has unexpected number of return values: %v

What it means

The SDF invoker requires SplitRestriction to return either 1 value (slice of restrictions) or 2 values (slice + error); other arities hit the panic fallback. This enforces the splittable DoFn method contract at invocation time.

Source

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

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

		n.call = func() (splits any, err error) {
			ret := n.fn.Fn.Call(n.args)

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

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

	return nil
}

func (n *rsInvoker) initCallFn() error {
	// Expects a signature of the form:
	// (context.Context?, key?, value, restriction) (float64, 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() (size float64, 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 SplitRestriction return exactly ([]Restriction) or ([]Restriction, error)
  2. Verify the signature against the Beam Go SDF documentation
  3. Regenerate/check any code that wraps the DoFn so the arity matches

Example fix

// before
func (fn *sdfFn) SplitRestriction(r Rest, n int) ([]Rest, int, error) { ... }

// after
func (fn *sdfFn) SplitRestriction(r Rest) ([]Rest, error) { ... }
Defensive patterns

Strategy: validation

Validate before calling

m := reflect.ValueOf(fn).MethodByName("SplitRestriction")
if m.IsValid() && m.Type().NumOut() != 1 && m.Type().NumOut() != 2 {
    return fmt.Errorf("SplitRestriction must return 1 or 2 values")
}

Type guard

func validSplitRestriction(fn interface{}) bool {
    m := reflect.ValueOf(fn).MethodByName("SplitRestriction")
    if !m.IsValid() { return false }
    n := m.Type().NumOut()
    return n == 1 || n == 2
}

Try / catch

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

Prevention

When it happens

Trigger: A DoFn's SplitRestriction returns 0 or 3+ values; the generated dispatcher has no case for that arity and panics during pipeline execution.

Common situations: Hand-written SDFs with incorrect SplitRestriction signatures; refactorings that changed return counts without updating the SDF contract.

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/0ba86d1970a7ccdb. Report an issue: GitHub.