{"record":{"id":"98f2191a3ee9c411","repo":"apache/beam","slug":"method-v-missing-sdf-rtracker-expected-one-at-index-v","errorCode":null,"errorMessage":"method %v missing sdf.RTracker, expected one at index %v","messagePattern":"method (.+?) missing sdf\\.RTracker, expected one at index (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":884,"sourceCode":"\t\tisSdf = true\n\tcase len(requiredSdfNames): // No SDF methods.\n\t\tisSdf = false\n\tdefault: // Anything else means an invalid # of SDF methods.\n\t\terr := errors.Errorf(\"not all required SplittableDoFn methods are present. Missing methods: %v\", missing)\n\t\treturn false, err\n\t}\n\n\tprocessFn := fn.methods[processElementName]\n\tif pos, ok := processFn.RTracker(); ok != isSdf {\n\t\tif ok {\n\t\t\terr := errors.Errorf(\"method %v has sdf.RTracker as param %v, expected none\",\n\t\t\t\tprocessElementName, pos)\n\t\t\treturn false, errors.SetTopLevelMsgf(err, \"Method %v has an sdf.RTracker parameter at index %v, \"+\n\t\t\t\t\"but is not part of a splittable DoFn. sdf.RTracker is invalid in %v in non-splittable DoFns.\",\n\t\t\t\tprocessElementName, pos, processElementName)\n\t\t}\n\t\tpos, _, _ = processFn.Inputs()\n\t\terr := errors.Errorf(\"method %v missing sdf.RTracker, expected one at index %v\",\n\t\t\tprocessElementName, pos)\n\t\treturn false, errors.SetTopLevelMsgf(err, \"Method %v is missing an sdf.RTracker \"+\n\t\t\t\"parameter despite being part of a splittable DoFn. %v in splittable DoFns requires an \"+\n\t\t\t\"sdf.RTracker parameter before main inputs (in this case, at index %v).\",\n\t\t\tprocessElementName, processElementName, pos)\n\t}\n\treturn isSdf, nil\n}\n\n// validateSdfSignatures validates that types in the SDF methods of a Fn are\n// consistent with each other (for example, element and restriction types should\n// match with each other). Returns an error if one is found, or nil if the\n// types are all valid.\n// TODO(BEAM-3301): Once SDF documentation is added to ParDo, add a comment\n// here to refer to that for specific details about what needs to be consistent.\nfunc validateSdfSignatures(fn *Fn, numMainIn mainInputs) error {\n\tnum := int(numMainIn)\n","sourceCodeStart":866,"sourceCodeEnd":902,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L866-L902","documentation":"The mirror of error 4908: the DoFn was identified as a SplittableDoFn (all required SDF methods present) but ProcessElement lacks an sdf.RTracker parameter before its main inputs. validateIsSdf computes the expected index from ProcessElement's Inputs() and returns this error from AsDoFn.","triggerScenarios":"Implementing CreateInitialRestriction/SplitRestriction/RestrictionSize (a full SDF set) but forgetting the sdf.RTracker first parameter in ProcessElement, or placing it after the main inputs; detected during AsDoFn in beam.ParDo.","commonSituations":"Migrating an existing DoFn to splittable by adding the SDF methods but not updating ProcessElement; removing RTracker while refactoring ProcessElement's signature; inserting other leading parameters (context, event time) and misplacing RTracker.","solutions":["Add an sdf.RTracker parameter to ProcessElement at the index stated in the error (before main inputs).","Ensure RTracker is positioned before the element/restriction main input parameters.","Return the RTracker from the restriction-creation path so it drives the bundle correctly."],"exampleFix":"// before\nfunc (fn *myFn) ProcessElement(w string, emit func(int)) {}\n// SDF methods present\n\n// after\nfunc (fn *myFn) ProcessElement(rt sdf.RTracker, w string, emit func(int)) { ... rt.TryClaim(...) ... }","handlingStrategy":"validation","validationCode":"// when all SDF methods exist, confirm ProcessElement starts with sdf.RTracker:\nt := reflect.TypeOf(fn)\nm, _ := t.MethodByName(\"ProcessElement\")\nif isCompleteSdf(fn) && m.Type.In(paramOffset) != reflect.TypeOf((*sdf.RTracker)(nil)).Elem() { /* add RTracker */ }","typeGuard":"func hasRTrackerFirst(fn interface{}) bool { t := reflect.TypeOf(fn); m, ok := t.MethodByName(\"ProcessElement\"); if !ok { return false }; rt := reflect.TypeOf((*sdf.RTracker)(nil)).Elem(); for i := 0; i < m.Type.NumIn(); i++ { if m.Type.In(i) == rt { return true } }; return false }","tryCatchPattern":"if err := beam.ParDo(s, fn, in); err != nil {\n\tif strings.Contains(err.Error(), \"missing sdf.RTracker\") { log.Fatalf(\"add RTracker at stated index: %v\", err) }\n}","preventionTips":["Migrate to SDF by adding RTracker to ProcessElement in the same change as the SDF methods","Keep RTracker as the first parameter after any context, before main inputs","Review ProcessElement's signature whenever toggling splittable behavior"],"tags":["go","apache-beam","splittable-dofn","sdf","rtracker"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}