{"record":{"id":"1b0a59fa7d647754","repo":"apache/beam","slug":"failed-to-expand-cross-language-transform-for-edge-v","errorCode":null,"errorMessage":"failed to expand cross language transform for edge: %v","messagePattern":"failed to expand cross language transform for edge: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/graphx/translate.go","lineNumber":745,"sourceCode":"\t\tInputs:        inputs,\n\t\tOutputs:       outputs,\n\t\tEnvironmentId: transformEnvID,\n\t\tAnnotations:   annotations,\n\t}\n\tm.transforms[id] = transform\n\tallPIds = append(allPIds, id)\n\treturn allPIds, nil\n}\n\nfunc (m *marshaller) expandCrossLanguage(namedEdge NamedEdge) (string, error) {\n\tedge := namedEdge.Edge\n\tid := edgeID(edge)\n\n\tinputs := make(map[string]string)\n\n\tfor tag, n := range ExternalInputs(edge) {\n\t\tif _, err := m.addNode(n); err != nil {\n\t\t\treturn \"\", errors.Wrapf(err, \"failed to expand cross language transform for edge: %v\", namedEdge)\n\t\t}\n\t\t// Ignore tag if it is a dummy UnnamedInputTag\n\t\tif tag == graph.UnnamedInputTag {\n\t\t\ttag = fmt.Sprintf(\"i%v\", edge.External.InputsMap[tag])\n\t\t}\n\t\tinputs[tag] = nodeID(n)\n\t}\n\n\tspec := &pipepb.FunctionSpec{\n\t\tUrn:     edge.External.Urn,\n\t\tPayload: edge.External.Payload,\n\t}\n\n\ttransform := &pipepb.PTransform{\n\t\tUniqueName:    namedEdge.Name,\n\t\tSpec:          spec,\n\t\tInputs:        inputs,\n\t\tEnvironmentId: m.addDefaultEnv(),","sourceCodeStart":727,"sourceCodeEnd":763,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/graphx/translate.go#L727-L763","documentation":"expandCrossLanguage serializes an ExternalTransform edge: it first adds every external input node to the model. If m.addNode fails for any input, the error is wrapped as 'failed to expand cross language transform for edge: %v'. It is a wrapper over a deeper failure (e.g. makeNode/addWindowingStrategy) while expanding a cross-language transform.","triggerScenarios":"Calling beam.CrossLanguage / an ExternalTransform edge whose input PCollection nodes cannot be marshalled — typically the underlying windowing strategy marshal or coder registration failed inside addNode.","commonSituations":"Cross-language pipelines (Go driving Python/Java transforms) with exotic windowing or coders on the input side; mismatched SDK versions where the expanded payload references unsupported features.","solutions":["Inspect the wrapped inner error to find the true failure (coder or windowing strategy marshal)","Check the input PCollections' coders/windowing are supported by the runner-API marshalling","Ensure all SDKs' container images / expansion service versions are compatible","Report upstream with the full wrapped error chain if the input is a plain default PCollection"],"exampleFix":"// before\nif _, err := m.addNode(n); err != nil {\n    return \"\", errors.Wrapf(err, \"failed to expand cross language transform for edge: %v\", namedEdge)\n}\n// after — log the offending node/tag for diagnosis\nif _, err := m.addNode(n); err != nil {\n    return \"\", errors.Wrapf(err, \"failed to expand cross language transform for edge %v input tag %q\", namedEdge, tag)\n}","handlingStrategy":"try-catch","validationCode":"// verify inputs are plain, marshalable PCollections before CrossLanguage\nfor _, in := range extInputs {\n    if in == nil || in.Coder == nil {\n        return errors.New(\"external transform input missing coder\")\n    }\n}","typeGuard":"func validExternalInput(n *graph.Node) bool { return n != nil && n.Coder != nil && n.WindowingStrategy() != nil }","tryCatchPattern":"if err := beam.Run(ctx, pr); err != nil {\n    var wrapped *errors.Wrapped\n    if errors.As(err, &wrapped) && strings.Contains(err.Error(), \"failed to expand cross language transform\") {\n        log.Printf(\"cross-language expansion failed: %v\", err)\n        // fall back to pure-Go transform or fix expansion service\n    }\n    return err\n}","preventionTips":["Pin expansion service and all SDK container versions to the same Beam release","Keep inputs to external transforms with standard coders/windowing","Test cross-language pipelines end-to-end in CI"],"tags":["go","apache-beam","cross-language","external-transform"],"backgroundTag":"unexpected-response-shape","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"}