{"record":{"id":"c614294476e41b8d","repo":"apache/beam","slug":"number-of-side-inputs-in-method-v-does-not-match-method-v-fn","errorCode":null,"errorMessage":"number of side inputs in method %v does not match method %v: got %d, expected either %d or %d","messagePattern":"number of side inputs in method (.+?) does not match method (.+?): got (.+?), expected either (.+?) or (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":814,"sourceCode":"\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.\n\tposMethodIn, numMethodIn, ok := method.Inputs()\n\tnumProcessIn := len(processFnInputs)\n\n\t// Handle cases where method has no inputs.\n\tif !ok {\n\t\t// If there's no inputs, this is fine, as the ProcessElement method could be a\n\t\t// CoGBK, and not have side inputs.\n\t\treturn nil\n\t}\n\n\t// Error if number of side inputs doesn't match any of the possible numbers of side inputs,\n\t// defined below.\n\tnumSideInSingle := numProcessIn - int(MainSingle)\n\tnumSideInKv := numProcessIn - int(MainKv)\n\tif numMethodIn != numSideInSingle && numMethodIn != numSideInKv {\n\t\terr := errors.Errorf(\"number of side inputs in method %v does not match method %v: got %d, expected either %d or %d\",\n\t\t\tmethodName, processElementName, numMethodIn, numSideInSingle, numSideInKv)\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\t// If there's N inputs in the method, then we compare with the last N inputs to processElement.\n\toffset := numProcessIn - numMethodIn\n\tsideInputs := processFnInputs[offset:]\n\tfor i := 0; i < numMethodIn; 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,","sourceCodeStart":796,"sourceCodeEnd":832,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L796-L832","documentation":"For DoFn methods where the main input cardinality is unknown (single vs KV), validateSideInputsNumUnknown accepts only two possible side input counts: numProcessIn - 1 (main is single) or numProcessIn - 2 (main is KV). This error is thrown from AsDoFn when the auxiliary method's input count matches neither, meaning the number of side inputs is inconsistent with ProcessElement under either interpretation.","triggerScenarios":"A StartBundle/FinishBundle/Setup/Teardown method declaring a number of inputs such that, after subtracting either 1 (MainSingle) or 2 (MainKv) main inputs, the remainder never equals ProcessElement's side input count; e.g. an extra context or unexpected parameter shifting the count.","commonSituations":"Auxiliary method includes extra parameters (context, event time, etc.) not present in the expected shape; mixing a KV-form ProcessElement with a wrongly sized auxiliary method; hand-writing signatures instead of mirroring ProcessElement.","solutions":["Adjust the auxiliary method's input count so inputs minus 1 (single-element form) or minus 2 (KV form) equals ProcessElement's side input count.","Remove or add side input parameters to match one of the two accepted shapes.","Mirror ProcessElement's parameter list exactly, changing only the main input form."],"exampleFix":"// before (ProcessElement has 1 main + 2 side inputs = 3 params)\nfunc (fn *myFn) FinishBundle(a beam.V, b beam.V) {} // only 2 inputs\n\n// after\nfunc (fn *myFn) FinishBundle(w string, a beam.V, b beam.V) {} // 1 main + 2 side inputs","handlingStrategy":"validation","validationCode":"// accepted shapes for auxiliary method inputs: len(PE params) - 1 or len(PE params) - 2\nn := numProcessElementInputs\nok := auxInputs == n-1 || auxInputs == n-2","typeGuard":"func auxInputCountValid(aux, pe int) bool { return aux == pe-1 || aux == pe-2 }","tryCatchPattern":"if err := beam.ParDo(s, fn, in); err != nil { log.Fatalf(\"side input count: %v\", err) }","preventionTips":["Mirror ProcessElement's parameter list in auxiliary methods, changing only the main input form","Do not add extra parameters (ctx, timestamps) ad hoc to auxiliary methods","Test signature registration early with a tiny pipeline"],"tags":["go","apache-beam","dofn","side-input","signature-validation"],"backgroundTag":"schema-validation-failed","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"}