apache/beam · error

Mismatched restriction tracker type in method

Error message

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.

What it means

Apache Beam Go validates splittable DoFn (SDF) method signatures at graph construction time. The TruncateRestriction method must take the restriction tracker type (as declared by CreateTracker) as its first parameter. This error is raised when the parameter at the SDF-required start index has a different reflect.Type than the tracker implementation returned by CreateTracker.

Solutions

  1. Change the first parameter of TruncateRestriction to the exact tracker type returned by CreateTracker (e.g. *sdf.LockRTracker wrapping your restriction tracker if that is what CreateTracker returns).
  2. Verify createTrackerName's return type in your DoFn and make TruncateRestriction's tracker parameter match it exactly.
  3. Re-run your pipeline; the error includes Got/Want reflect types to compare directly.

Example fix

// before
func (fn *myFn) TruncateRestriction(rt *otherTracker, r MyRestriction) MyRestriction { ... }
// after
func (fn *myFn) TruncateRestriction(rt *sdf.LockRTracker, r MyRestriction) MyRestriction { ... }
Defensive patterns

Strategy: validation

Validate before calling

func validateTruncateSig(fn interface{}) error {
    // validate via Beam's own API at startup:
    if _, err := beam.TryCreateDoFn(reflect.TypeOf(fn)); err != nil {
        return fmt.Errorf("DoFn signature invalid: %w", err)
    }
    return nil
}

Type guard

func okTruncate(fn *myFn) bool {
    t := reflect.TypeOf(fn)
    m, ok := t.MethodByName("TruncateRestriction")
    if !ok || m.Type.NumIn() < 3 { return false }
    c, ok2 := t.MethodByName("CreateTracker")
    return ok2 && m.Type.In(1) == c.Type.Out(0)
}

Prevention

When it happens

Trigger: Defining a DoFn with a TruncateRestriction method whose first non-restriction parameter type does not equal the type returned by the DoFn's CreateTracker method, e.g. TruncateRestriction(rt *myWrongTracker, r MyRestriction) while CreateTracker returns *MyTracker.

Common situations: Refactoring a restriction type and forgetting to update TruncateRestriction; copying an SDF from another DoFn without matching tracker types; using a wrapper or interface type instead of the concrete tracker implementation.

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/651d5740595a1818. Report an issue: GitHub.

Appendix: source

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

					createTrackerName, 0, method.Ret[0].T, processFn.Param[pos].T, processElementName)
			}
		}
	}

	rTrackerImplT := fn.methods[createTrackerName].Ret[0].T

	for _, name := range optionalSdfNames {
		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())

View on GitHub (pinned to 12126d8942)