apache/beam · error

Invalid output type in method

Error message

Invalid output type in method %v, return value at index %v. Got: %v, Want: %v (from method %v). Ensure that all restrictions in an SDF are the same type.

What it means

Beam Go requires that TruncateRestriction in a splittable DoFn returns a value whose type matches the restriction type produced by CreateInitialRestriction. This error fires when the first return value's reflect.Type differs from restrictionT, ensuring all restrictions in an SDF are the same type.

Solutions

  1. Make TruncateRestriction's return type identical to the type returned by CreateInitialRestriction.
  2. Check the Got/Want types in the message and align struct definitions or use the same named type instead of distinct aliases.
  3. If you genuinely need a different restriction, redesign the SDF so one restriction type is used throughout (CreateInitialRestriction, CreateTracker, SplitRestriction, TruncateRestriction, ProcessElement).

Example fix

// before
func (fn *f) CreateInitialRestriction(elems []E) rangeT { ... }
func (fn *f) TruncateRestriction(t *tracker, r rangeT) rangeT2 { ... }
// after
func (fn *f) TruncateRestriction(t *tracker, r rangeT) rangeT { ... }
Defensive patterns

Strategy: validation

Validate before calling

func validateRestrictionTypes(fn interface{}) error {
    t := reflect.TypeOf(fn)
    ci, ok1 := t.MethodByName("CreateInitialRestriction")
    tr, ok2 := t.MethodByName("TruncateRestriction")
    if ok1 && ok2 && ci.Type.Out(0) != tr.Type.Out(0) {
        return fmt.Errorf("restriction types differ: %v vs %v", ci.Type.Out(0), tr.Type.Out(0))
    }
    return nil
}

Type guard

func sameRestrictionType(fn interface{}) bool {
    t := reflect.TypeOf(fn)
    ci, a := t.MethodByName("CreateInitialRestriction")
    tr, b := t.MethodByName("TruncateRestriction")
    return a && b && ci.Type.Out(0) == tr.Type.Out(0)
}

Prevention

When it happens

Trigger: TruncateRestriction returning a different restriction type than CreateInitialRestriction, e.g. returning a pointer where the initial restriction is a value type, or truncating into a different struct.

Common situations: Introducing a second restriction type during refactors; returning a wrapped/aliased restriction type; hand-writing TruncateRestriction after defining CreateInitialRestriction with a distinct struct.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at sdks/go/pkg/beam/core/graph/fn.go:1100

		method, ok := fn.methods[name]
		if !ok {
			continue
		}

		startIdx := sdfRequiredParamStartIndex(method)

		switch name {
		case truncateRestrictionName:
			if method.Param[startIdx].T != rTrackerImplT {
				err := errors.Errorf("mismatched restriction tracker type in method %v, param %v. got: %v, want: %v",
					truncateRestrictionName, startIdx, method.Param[startIdx].T, rTrackerImplT)
				return errors.SetTopLevelMsgf(err, "Mismatched restriction tracker type in method %v, "+
					"parameter at index %v. Got: %v, Want: %v (from method %v). "+
					"Ensure that restriction tracker is the first parameter.",
					truncateRestrictionName, startIdx, method.Param[startIdx].T, rTrackerImplT, createTrackerName)
			}
			if method.Ret[0].T != restrictionT {
				err := errors.Errorf("invalid output type in method %v, return %v. got: %v, want: %v",
					truncateRestrictionName, 0, method.Ret[0].T, restrictionT)
				return errors.SetTopLevelMsgf(err, "Invalid output type in method %v, "+
					"return value at index %v. Got: %v, Want: %v (from method %v). "+
					"Ensure that all restrictions in an SDF are the same type.",
					truncateRestrictionName, 0, method.Ret[0].T, restrictionT, createInitialRestrictionName)
			}
			processFn := fn.methods[processElementName]
			if _, exists := processFn.ProcessContinuation(); !exists {
				err := errors.Errorf("missing return value in %v: return value of type %v is not present",
					processElementName, reflect.TypeOf((*sdf.ProcessContinuation)(nil)).Elem())
				return errors.SetTopLevelMsgf(err, "Missing output value in method %v, "+
					"%v method should return %v when %v method is defined.",
					processElementName, processElementName, reflect.TypeOf((*sdf.ProcessContinuation)(nil)).Elem(), truncateRestrictionName)
			}
		}
	}

	return nil

View on GitHub (pinned to 12126d8942)