{"record":{"id":"233d5f347721cf54","repo":"apache/beam","slug":"invalid-dofn","errorCode":null,"errorMessage":"invalid DoFn","messagePattern":"invalid DoFn","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":477,"sourceCode":"// CoGBKMainInput is an optional config to NewDoFn which specifies the number\n// of components of a CoGBK input to the DoFn being created, allowing for more complete\n// validation.\n//\n// Example usage:\n//\n//\tvar col beam.PCollection\n//\tgraph.NewDoFn(fn, graph.CoGBKMainInput(len(col.Type().Components())))\nfunc CoGBKMainInput(components int) func(*config) {\n\treturn func(cfg *config) {\n\t\tcfg.numMainIn = mainInputs(components)\n\t}\n}\n\n// NewDoFn constructs a DoFn from the given value, if possible.\nfunc NewDoFn(fn any, options ...func(*config)) (*DoFn, error) {\n\tret, err := NewFn(fn)\n\tif err != nil {\n\t\treturn nil, errors.WithContext(errors.Wrapf(err, \"invalid DoFn\"), \"constructing DoFn\")\n\t}\n\tcfg := defaultConfig()\n\tfor _, opt := range options {\n\t\topt(cfg)\n\t}\n\treturn AsDoFn(ret, cfg.numMainIn)\n}\n\n// AsDoFn converts a Fn to a DoFn, if possible. numMainIn specifies how many\n// main inputs are expected in the DoFn's method signatures. Valid inputs are\n// the package constants of type mainInputs. If that number is MainUnknown then\n// validation is done by best effort and may miss some edge cases.\nfunc AsDoFn(fn *Fn, numMainIn mainInputs) (*DoFn, error) {\n\taddContext := func(err error, fn *Fn) error {\n\t\treturn errors.WithContextf(err, \"graph.AsDoFn: for Fn named %v\", fn.Name())\n\t}\n\n\tif fn.methods == nil {","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L459-L495","documentation":"NewDoFn wraps any error from NewFn (or AsDoFn) and adds the message \"invalid DoFn\" plus context naming the DoFn being constructed. It is the top-level error users see when a DoFn value fails reflection or signature validation.","triggerScenarios":"Calling NewDoFn (or indirectly beam.ParDo/beam.TryParDo) with an invalid value or a struct whose method signatures fail validation — the underlying cause is chained.","commonSituations":"Wrong receiver type, unsupported method signatures, missing ProcessElement on a structural DoFn; typically during pipeline graph construction at submit time.","solutions":["Read the wrapped cause for the real failure (method invalid, wrong kind, missing ProcessElement, bad params)","Fix the DoFn value/signature accordingly","Validate the fn in a unit test with graph.NewDoFn before running the pipeline"],"exampleFix":"// before\nbeam.ParDo(s, myFnValue, in) // structural fn passed by value\n// after\nbeam.ParDo(s, &myFnValue, in)","handlingStrategy":"try-catch","validationCode":"if _, err := graph.NewDoFn(myFn); err != nil { return fmt.Errorf(\"DoFn %T invalid: %w\", myFn, err) }","typeGuard":null,"tryCatchPattern":"ret, err := graph.NewDoFn(fn)\nif err != nil {\n    var ec errctx.Error\n    if errors.As(err, &ec) { log.Printf(\"context: %v\", ec.Context) }\n    return fmt.Errorf(\"constructing DoFn: %w\", err)\n}","preventionTips":["Unwrap and read the root cause before changing code","Add graph.NewDoFn smoke tests for every custom DoFn"],"tags":["go","apache-beam","dofn"],"backgroundTag":"invalid-argument-value","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"}