{"record":{"id":"582091bc41b03f84","repo":"apache/beam","slug":"invalid-output-type-in-method-v-return-value-at-index-v-got-582091","errorCode":null,"errorMessage":"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.","messagePattern":"Invalid output type in method (.+?), return value at index (.+?)\\. Got: (.+?), Want: (.+?) \\(from method (.+?)\\)\\. Ensure that all restrictions in an SDF are the same type\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":1100,"sourceCode":"\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())\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"Missing output value in method %v, \"+\n\t\t\t\t\t\"%v method should return %v when %v method is defined.\",\n\t\t\t\t\tprocessElementName, processElementName, reflect.TypeOf((*sdf.ProcessContinuation)(nil)).Elem(), truncateRestrictionName)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil","sourceCodeStart":1082,"sourceCodeEnd":1118,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L1082-L1118","documentation":"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.","triggerScenarios":"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.","commonSituations":"Introducing a second restriction type during refactors; returning a wrapped/aliased restriction type; hand-writing TruncateRestriction after defining CreateInitialRestriction with a distinct struct.","solutions":["Make TruncateRestriction's return type identical to the type returned by CreateInitialRestriction.","Check the Got/Want types in the message and align struct definitions or use the same named type instead of distinct aliases.","If you genuinely need a different restriction, redesign the SDF so one restriction type is used throughout (CreateInitialRestriction, CreateTracker, SplitRestriction, TruncateRestriction, ProcessElement)."],"exampleFix":"// before\nfunc (fn *f) CreateInitialRestriction(elems []E) rangeT { ... }\nfunc (fn *f) TruncateRestriction(t *tracker, r rangeT) rangeT2 { ... }\n// after\nfunc (fn *f) TruncateRestriction(t *tracker, r rangeT) rangeT { ... }","handlingStrategy":"validation","validationCode":"func validateRestrictionTypes(fn interface{}) error {\n    t := reflect.TypeOf(fn)\n    ci, ok1 := t.MethodByName(\"CreateInitialRestriction\")\n    tr, ok2 := t.MethodByName(\"TruncateRestriction\")\n    if ok1 && ok2 && ci.Type.Out(0) != tr.Type.Out(0) {\n        return fmt.Errorf(\"restriction types differ: %v vs %v\", ci.Type.Out(0), tr.Type.Out(0))\n    }\n    return nil\n}","typeGuard":"func sameRestrictionType(fn interface{}) bool {\n    t := reflect.TypeOf(fn)\n    ci, a := t.MethodByName(\"CreateInitialRestriction\")\n    tr, b := t.MethodByName(\"TruncateRestriction\")\n    return a && b && ci.Type.Out(0) == tr.Type.Out(0)\n}","tryCatchPattern":null,"preventionTips":["Use one named restriction type for the whole SDF; avoid distinct aliases of the same underlying struct.","Write a table test instantiating the DoFn with beam.TryCreateDoFn to catch signature drift."],"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"}