{"record":{"id":"578d99d893bd3383","repo":"apache/beam","slug":"side-input-in-method-v-does-not-match-side-input-in-v","errorCode":null,"errorMessage":"side input in method %v does not match side input in %v","messagePattern":"side input in method (.+?) does not match side input in (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":780,"sourceCode":"\t}\n\n\t// Error if number of side inputs doesn't match.\n\tif numMethodIn != numSideIn {\n\t\terr := errors.Errorf(\"number of side inputs in method %v does not match method %v: got %d, expected %d\",\n\t\t\tmethodName, processElementName, numMethodIn, numSideIn)\n\t\treturn errors.SetTopLevelMsgf(err,\n\t\t\t\"Incorrect number of side inputs in the %v method of a DoFn. \"+\n\t\t\t\t\"The side inputs should match those of the %v method.\",\n\t\t\tmethodName, processElementName)\n\t}\n\n\t// Error if there's a type mismatch.\n\tmethodInputs := method.Param[posMethodIn : posMethodIn+numMethodIn]\n\tsideInputs := processFnInputs[numMainIn:] // Skip main inputs in ProcessFn\n\tfor i := 0; i < len(sideInputs); i++ {\n\t\tif sideInputs[i].T != methodInputs[i].T {\n\t\t\tvar err error = &funcx.TypeMismatchError{Got: methodInputs[i].T, Want: sideInputs[i].T}\n\t\t\terr = errors.Wrapf(err, \"side input in method %v does not match side input in %v\",\n\t\t\t\tmethodName, processElementName)\n\t\t\treturn errors.SetTopLevelMsgf(err,\n\t\t\t\t\"Incorrect side inputs in the %v method of a DoFn. \"+\n\t\t\t\t\t\"The side inputs should match those of the %v method.\",\n\t\t\t\tmethodName, processElementName)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// validateSideInputsNumUnknown does similar validation as validateSideInputs, but for an unknown\n// number of main inputs.\nfunc validateSideInputsNumUnknown(processFnInputs []funcx.FnParam, method *funcx.Fn, methodName string) error {\n\t// Note: By the time this is called, we should have already know that ProcessElement has at\n\t// least two inputs, and the second input is ambiguous (could be either a main input or side\n\t// input). Since we don't know how to interpret the second input, these checks will be more\n\t// permissive than they would be otherwise.","sourceCodeStart":762,"sourceCodeEnd":798,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L762-L798","documentation":"After counts match, validateSideInputs compares each side input's type: the i-th side input parameter of the auxiliary method must have the same type as the i-th side input of ProcessElement (skipping main inputs). A funcx.TypeMismatchError wrapped with this message is returned from AsDoFn on mismatch.","triggerScenarios":"Declaring ProcessElement side input as beam.V (single value) but auxiliary method side input as beam.KV, or different element types (e.g. Iter[string] vs string), then converting the DoFn with AsDoFn.","commonSituations":"Side input built with beam.Input yielding KV vs single values; switching a side input's underlying PCollection type without updating methods; using beam.V/beam.KV constants inconsistently across methods.","solutions":["Make each auxiliary method side input type exactly equal to the corresponding ProcessElement side input type.","Check whether the side input PCollection should be KV (use beam.KV and a KV side input) or single value (beam.V).","Update the pipeline's beam.Input/side input construction if the element type changed intentionally."],"exampleFix":"// before\nfunc (fn *myFn) ProcessElement(w string, side beam.V) {}\nfunc (fn *myFn) FinishBundle(side beam.KV) {}\n\n// after\nfunc (fn *myFn) ProcessElement(w string, side beam.V) {}\nfunc (fn *myFn) FinishBundle(side beam.V) {}","handlingStrategy":"validation","validationCode":"// check side input PCollection type before wiring:\n// KV side input -> beam.KV params; single-value side input -> beam.V params","typeGuard":"func isKvSideInput(t reflect.Type) bool { return strings.Contains(t.String(), \"KV\") }","tryCatchPattern":"if err := buildPipeline(); err != nil {\n\tvar tm *funcx.TypeMismatchError\n\tif errors.As(err, &tm) { log.Fatalf(\"side input type: got %v want %v\", tm.Got, tm.Want) }\n}","preventionTips":["Copy side input parameter declarations verbatim from ProcessElement","Decide V vs KV per side input once and use it in every method","Update all methods when a side input PCollection's element type changes"],"tags":["go","apache-beam","dofn","side-input","type-mismatch"],"backgroundTag":"type-mismatch","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"}