{"record":{"id":"e92cb56285e8ac41","repo":"apache/beam","slug":"not-all-required-splittabledofn-methods-are-present-missing","errorCode":null,"errorMessage":"not all required SplittableDoFn methods are present. Missing methods: %v","messagePattern":"not all required SplittableDoFn methods are present\\. Missing methods: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":870,"sourceCode":"//   - Not include an RTracker parameter in ProcessElement.\nfunc validateIsSdf(fn *Fn) (bool, error) {\n\t// Store missing method names so we can output them to the user if validation fails.\n\tvar missing []string\n\tfor _, name := range requiredSdfNames {\n\t\t_, ok := fn.methods[name]\n\t\tif !ok {\n\t\t\tmissing = append(missing, name)\n\t\t}\n\t}\n\n\tvar isSdf bool\n\tswitch len(missing) {\n\tcase 0: // All SDF methods present.\n\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).\",","sourceCodeStart":852,"sourceCodeEnd":888,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L852-L888","documentation":"A SplittableDoFn must implement all required SDF methods (e.g. CreateInitialRestriction, SplitRestriction, RestrictionSize, TruncateRestriction). validateIsSdf, called from AsDoFn, tolerates either zero or all required methods; a partial set (some present, some missing) means an invalid SplittableDoFn and produces this error listing the missing methods.","triggerScenarios":"Implementing only some SDF methods on a DoFn (e.g. CreateInitialRestriction but not RestrictionSize), then registering it with beam.ParDo during graph construction; also occurs if a required method was deleted or renamed.","commonSituations":"Partially migrating a classic DoFn to an SDF; a rename/refactor removing one required method; copying an SDF example but omitting a method the author thought optional.","solutions":["Implement every missing method listed in the error message (all requiredSdfNames).","If splitting is not intended, remove all SDF methods so the DoFn is a plain DoFn.","Verify the sdf.RTracker parameter in ProcessElement matches a fully implemented SDF."],"exampleFix":"// before\nfunc (fn *myFn) CreateInitialRestriction(rangeSize int) offsetrange.Restriction { ... }\n// missing SplitRestriction / RestrictionSize\n\n// after\nfunc (fn *myFn) CreateInitialRestriction(rangeSize int) offsetrange.Restriction { ... }\nfunc (fn *myFn) SplitRestriction(rs offsetrange.Restriction) []offsetrange.Restriction { ... }\nfunc (fn *myFn) RestrictionSize(rs offsetrange.Restriction) float64 { ... }","handlingStrategy":"validation","validationCode":"// before registering an SDF, assert all required methods exist:\nrequired := []string{\"CreateInitialRestriction\", \"SplitRestriction\", \"RestrictionSize\"}\nfor _, m := range required {\n\tif _, ok := reflect.TypeOf(fn).MethodByName(m); !ok { return fmt.Errorf(\"missing %s\", m) }\n}","typeGuard":"func isCompleteSdf(fn interface{}) bool { t := reflect.TypeOf(fn); for _, m := range requiredSdfNames { if _, ok := t.MethodByName(m); !ok { return false } }; return true }","tryCatchPattern":"if !isCompleteSdf(&myFn{}) { /* implement all SDF methods or drop RTracker */ }\nif err := beam.ParDo(s, &myFn{}, in); err != nil { log.Fatalf(\"SDF incomplete: %v\", err) }","preventionTips":["Treat SDF methods as an all-or-nothing set; scaffold them together","Grep for CreateInitialRestriction and verify its siblings exist when editing an SDF","Start from the Beam SDF example and keep all methods in one file"],"tags":["go","apache-beam","splittable-dofn","sdf","signature-validation"],"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"}