{"record":{"id":"651d5740595a1818","repo":"apache/beam","slug":"mismatched-restriction-tracker-type-in-method-v-parameter-at","errorCode":null,"errorMessage":"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.","messagePattern":"Mismatched restriction tracker type in method (.+?), parameter at index (.+?)\\. Got: (.+?), Want: (.+?) \\(from method (.+?)\\)\\. Ensure that restriction tracker is the first parameter\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":1092,"sourceCode":"\t\t\t\t\tcreateTrackerName, 0, method.Ret[0].T, processFn.Param[pos].T, processElementName)\n\t\t\t}\n\t\t}\n\t}\n\n\trTrackerImplT := fn.methods[createTrackerName].Ret[0].T\n\n\tfor _, name := range optionalSdfNames {\n\t\tmethod, ok := fn.methods[name]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tstartIdx := sdfRequiredParamStartIndex(method)\n\n\t\tswitch name {\n\t\tcase truncateRestrictionName:\n\t\t\tif method.Param[startIdx].T != rTrackerImplT {\n\t\t\t\terr := errors.Errorf(\"mismatched restriction tracker type in method %v, param %v. got: %v, want: %v\",\n\t\t\t\t\ttruncateRestrictionName, startIdx, method.Param[startIdx].T, rTrackerImplT)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"Mismatched restriction tracker type in method %v, \"+\n\t\t\t\t\t\"parameter at index %v. Got: %v, Want: %v (from method %v). \"+\n\t\t\t\t\t\"Ensure that restriction tracker is the first parameter.\",\n\t\t\t\t\ttruncateRestrictionName, startIdx, method.Param[startIdx].T, rTrackerImplT, createTrackerName)\n\t\t\t}\n\t\t\tif method.Ret[0].T != restrictionT {\n\t\t\t\terr := errors.Errorf(\"invalid output type in method %v, return %v. got: %v, want: %v\",\n\t\t\t\t\ttruncateRestrictionName, 0, method.Ret[0].T, restrictionT)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"Invalid output type in method %v, \"+\n\t\t\t\t\t\"return value at index %v. Got: %v, Want: %v (from method %v). \"+\n\t\t\t\t\t\"Ensure that all restrictions in an SDF are the same type.\",\n\t\t\t\t\ttruncateRestrictionName, 0, method.Ret[0].T, restrictionT, createInitialRestrictionName)\n\t\t\t}\n\t\t\tprocessFn := fn.methods[processElementName]\n\t\t\tif _, exists := processFn.ProcessContinuation(); !exists {\n\t\t\t\terr := errors.Errorf(\"missing return value in %v: return value of type %v is not present\",\n\t\t\t\t\tprocessElementName, reflect.TypeOf((*sdf.ProcessContinuation)(nil)).Elem())","sourceCodeStart":1074,"sourceCodeEnd":1110,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L1074-L1110","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","Verify createTrackerName's return type in your DoFn and make TruncateRestriction's tracker parameter match it exactly.","Re-run your pipeline; the error includes Got/Want reflect types to compare directly."],"exampleFix":"// before\nfunc (fn *myFn) TruncateRestriction(rt *otherTracker, r MyRestriction) MyRestriction { ... }\n// after\nfunc (fn *myFn) TruncateRestriction(rt *sdf.LockRTracker, r MyRestriction) MyRestriction { ... }","handlingStrategy":"validation","validationCode":"func validateTruncateSig(fn interface{}) error {\n    // validate via Beam's own API at startup:\n    if _, err := beam.TryCreateDoFn(reflect.TypeOf(fn)); err != nil {\n        return fmt.Errorf(\"DoFn signature invalid: %w\", err)\n    }\n    return nil\n}","typeGuard":"func okTruncate(fn *myFn) bool {\n    t := reflect.TypeOf(fn)\n    m, ok := t.MethodByName(\"TruncateRestriction\")\n    if !ok || m.Type.NumIn() < 3 { return false }\n    c, ok2 := t.MethodByName(\"CreateTracker\")\n    return ok2 && m.Type.In(1) == c.Type.Out(0)\n}","tryCatchPattern":null,"preventionTips":["Keep CreateTracker's return type and TruncateRestriction's first parameter in the same code edit.","Run beam.TryCreateDoFn/DoFn validation in unit tests before submitting pipelines.","If CreateTracker wraps in sdf.LockRTracker, TruncateRestriction must accept the LockRTracker too."],"tags":["go","apache-beam","splittable-dofn","validation"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}