{"record":{"id":"2a90369307d79f7e","repo":"apache/beam","slug":"invalid-scope-validate","errorCode":null,"errorMessage":"invalid scope","messagePattern":"invalid scope","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/validate.go","lineNumber":50,"sourceCode":"\t}\n\treturn t.Components()[0], t.Components()[1]\n}\n\n// ValidateNonCompositeType panics if the type of the PCollection is not a\n// composite type. It returns the type.\nfunc ValidateNonCompositeType(col PCollection) typex.FullType {\n\tt := col.Type()\n\tif typex.IsComposite(t.Type()) {\n\t\tpanic(fmt.Sprintf(\"pcollection must be of non-composite type: %v\", col))\n\t}\n\treturn t\n}\n\n// validate validates and processes the input collection and options. Private convenience\n// function.\nfunc validate(s Scope, col PCollection, opts []Option) ([]SideInput, map[string]reflect.Type, error) {\n\tif !s.IsValid() {\n\t\treturn nil, nil, errors.New(\"invalid scope\")\n\t}\n\tif !col.IsValid() {\n\t\treturn nil, nil, errors.New(\"invalid main pcollection\")\n\t}\n\tside, defs := parseOpts(opts)\n\tfor i, in := range side {\n\t\tif !in.Input.IsValid() {\n\t\t\treturn nil, nil, errors.Errorf(\"invalid side pcollection: index %v\", i)\n\t\t}\n\t}\n\ttypedefs, err := makeTypedefs(defs)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn side, typedefs, nil\n}\n\nfunc makeTypedefs(list []TypeDefinition) (map[string]reflect.Type, error) {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/validate.go#L32-L68","documentation":"validate() is the shared pre-flight check used by transform constructors such as TryParDo and TryCombinePerKey. It rejects the call with \"invalid scope\" when the passed beam.Scope is not valid — i.e. it is the zero Scope (created via var s beam.Scope) rather than one derived from a pipeline. A zero Scope has no underlying real scope, so transforms cannot be added to it.","triggerScenarios":"Calling beam.TryParDo / beam.TryCombinePerKey (or their Must wrappers) with a Scope obtained from var s beam.Scope, a struct field never initialized, or a Scope taken before pipeline.New() — anything where s.IsValid() is false.","commonSituations":"Refactoring a pipeline into a function that takes beam.Scope but callers pass an uninitialized value; embedding a Scope in a struct declared without initialization; constructing transforms in a package-level var before a pipeline exists; copy-paste code that forgot s := p.Root().","solutions":["Obtain the scope from a real pipeline: p := beam.NewPipeline(); s := p.Root() (or s := scope.Scope(\"name\")) before calling the transform.","Check each code path that builds the Scope and ensure it derives from beam.NewPipeline().Root(), never from a zero value.","Prefer Must-constructors so panics surface at construction with a stack trace pointing at the bad scope.","Guard library helpers with `if !s.IsValid() { return fmt.Errorf(...) }` of your own to fail fast with context."],"exampleFix":"// before\nvar s beam.Scope\nbeam.ParDo0(s, &fn{}, col) // invalid scope\n\n// after\np := beam.NewPipeline()\ns := p.Root().Scope(\"myTransform\")\nbeam.ParDo0(s, &fn{}, col)","handlingStrategy":"validation","validationCode":"if !s.IsValid() {\n    return fmt.Errorf(\"transform requires a scope derived from beam.NewPipeline().Root()\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never store or pass a bare `var s beam.Scope`; always derive scopes from p.Root().","Use Must-style constructors so invalid scopes panic at the construction site with a stack trace.","When extracting pipeline code into helpers, make beam.Scope an explicit, initialized parameter."],"tags":["apache-beam","go","pipeline-construction"],"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"}