{"record":{"id":"b887fabb01d69340","repo":"apache/beam","slug":"scope-is-nil","errorCode":null,"errorMessage":"Scope is nil","messagePattern":"Scope is nil","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/graph.go","lineNumber":52,"sourceCode":"\n\troot *Scope\n}\n\n// New returns an empty graph with the scope set to the root.\nfunc New() *Graph {\n\troot := &Scope{id: 0, Label: \"root\", Parent: nil}\n\treturn &Graph{root: root}\n}\n\n// Root returns the root scope of the graph.\nfunc (g *Graph) Root() *Scope {\n\treturn g.root\n}\n\n// NewScope creates and returns a new scope that is a child of the supplied scope.\nfunc (g *Graph) NewScope(parent *Scope, name string) *Scope {\n\tif parent == nil {\n\t\tpanic(\"Scope is nil\")\n\t}\n\tid := len(g.scopes) + 1\n\ts := &Scope{id: id, Label: name, Parent: parent}\n\tg.scopes = append(g.scopes, s)\n\treturn s\n}\n\n// NewEdge creates a new edge of the graph in the supplied scope.\nfunc (g *Graph) NewEdge(parent *Scope) *MultiEdge {\n\tif parent == nil {\n\t\tpanic(\"Scope is nil\")\n\t}\n\tid := len(g.edges) + 1\n\te := &MultiEdge{id: id, parent: parent}\n\tg.edges = append(g.edges, e)\n\treturn e\n}\n","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/graph.go#L34-L70","documentation":"Graph.NewScope panics when the parent *Scope is nil. Every new scope in a Beam pipeline graph must descend from an existing scope so the graph remains connected; a nil parent indicates a mis-constructed pipeline.","triggerScenarios":"Calling graph.NewScope(nil, name), typically because a scope variable was never initialized or was lost through an API boundary.","commonSituations":"Storing the pipeline root scope in a struct field that was never set; helper functions returning nil scope on error paths that is then passed to NewScope; zero-value struct usage instead of p.NewScope(...) or beam.NewScope.","solutions":["Obtain the initial scope from the pipeline, e.g. beam.NewScope(p), before creating child scopes","Fix the helper/initialization that produced the nil parent scope","Guard custom transform constructors with a nil check on the incoming scope"],"exampleFix":"// before\nsub := graph.NewScope(parent, \"myTransform\") // parent may be nil\n// after\nif parent == nil {\n\tparent = beam.NewScope(p)\n}\nsub := graph.NewScope(parent, \"myTransform\")","handlingStrategy":"validation","validationCode":"if parent == nil {\n\treturn errors.New(\"nil scope passed to NewScope; obtain root scope via beam.NewScope(p)\")\n}","typeGuard":"func validScope(s *graph.Scope) bool { return s != nil }","tryCatchPattern":"func safeNewScope(g *graph.Graph, parent *graph.Scope, name string) (s *graph.Scope, err error) {\n\tdefer func() { if r := recover(); r != nil { err = fmt.Errorf(\"newScope: %v\", r) } }()\n\treturn g.NewScope(parent, name), nil\n}","preventionTips":["Always derive the first scope from the pipeline (beam.NewScope(p))","Handle error paths in helpers so they never return a nil scope","Nil-check scope parameters in custom composite transforms"],"tags":["go","beam","graph","nil-pointer"],"backgroundTag":"null-argument","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"}