{"record":{"id":"b1f5e49d156ed353","repo":"apache/beam","slug":"tried-converting-invalid-node","errorCode":null,"errorMessage":"tried converting invalid Node","messagePattern":"tried converting invalid Node","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/xlang.go","lineNumber":230,"sourceCode":"\tgraphx.VerifyNamedOutputs(&ext)\n\t// Using the expanded outputs, the graph's counterpart outputs are updated with bounded values\n\tgraphx.ResolveOutputIsBounded(edge, isBoundedUpdater)\n\n\treturn mapNodeToPCollection(graphx.ExternalOutputs(edge)), nil\n}\n\n// Wrapper functions to handle beam <-> graph boundaries\n\nfunc pCollectionToNode(p PCollection) *graph.Node {\n\tif !p.IsValid() {\n\t\tpanic(\"tried converting invalid PCollection\")\n\t}\n\treturn p.n\n}\n\nfunc nodeToPCollection(n *graph.Node) PCollection {\n\tif n == nil {\n\t\tpanic(\"tried converting invalid Node\")\n\t}\n\tc := PCollection{n}\n\tc.SetCoder(NewCoder(c.Type()))\n\treturn c\n}\n\nfunc mapPCollectionToNode(pMap map[string]PCollection) map[string]*graph.Node {\n\tif pMap == nil {\n\t\treturn nil\n\t}\n\n\tnMap := make(map[string]*graph.Node)\n\tfor k, p := range pMap {\n\t\tnMap[k] = pCollectionToNode(p)\n\t}\n\treturn nMap\n}\n","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/xlang.go#L212-L248","documentation":"nodeToPCollection wraps a graph.Node as a PCollection during cross-language pipeline translation. The library panics when the node pointer is nil, because a nil Node cannot carry a type or coder — proceeding would produce a corrupt pipeline graph. This is an internal invariant check that fires when pipeline translation produces an unexpected nil node.","triggerScenarios":"Calling nodeToPCollection (via mapNodeToPCollection) with a nil *graph.Node during cross-language expansion/translation, typically when an expansion result or predecessor node lookup returned nil.","commonSituations":"Cross-language (XLang) transforms referencing a PCollection that was never created or was removed; version mismatch between Beam SDKs where an expansion response lacks expected nodes; malformed pipeline construction with external transforms.","solutions":["Inspect the pipeline before Run: verify every external transform's expanded outputs are referenced by valid, non-nil PCollections","Check Beam Go SDK version compatibility with the expansion service and other language SDKs; upgrade to a matching release","Report a bug to the Beam project with the pipeline and expansion service logs if nil nodes arise from standard xlang usage"],"exampleFix":"// before: passing a possibly-nil node\npc := beam.PCollection{} // built from mapNodeToPCollection(maybeNilNode)\n\n// after: guard before conversion\nif n == nil {\n    return fmt.Errorf(\"expansion returned nil node for external transform output\")\n}\npc := nodeToPCollection(n)","handlingStrategy":"validation","validationCode":"if n == nil {\n    return fmt.Errorf(\"xlang expansion produced nil node; check external transform outputs\")\n}\npc := nodeToPCollection(n)","typeGuard":"func isValidNode(n *graph.Node) bool { return n != nil }","tryCatchPattern":"// Go panics are not recoverable at the panic site; wrap pipeline construction\nfunc buildPC(n *graph.Node) (pc PCollection, err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"nodeToPCollection failed: %v\", r)\n        }\n    }()\n    return nodeToPCollection(n), nil\n}","preventionTips":["Verify all external transform outputs exist before wiring the pipeline","Keep Beam Go SDK versions aligned with expansion services","Add nil checks when mapping expansion results to PCollections"],"tags":["go","apache-beam","xlang","panic"],"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"}