apache/beam · error
failed to expand cross language transform for edge: %v
Error message
failed to expand cross language transform for edge: %v
What it means
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.
Source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/translate.go:745
Inputs: inputs,
Outputs: outputs,
EnvironmentId: transformEnvID,
Annotations: annotations,
}
m.transforms[id] = transform
allPIds = append(allPIds, id)
return allPIds, nil
}
func (m *marshaller) expandCrossLanguage(namedEdge NamedEdge) (string, error) {
edge := namedEdge.Edge
id := edgeID(edge)
inputs := make(map[string]string)
for tag, n := range ExternalInputs(edge) {
if _, err := m.addNode(n); err != nil {
return "", errors.Wrapf(err, "failed to expand cross language transform for edge: %v", namedEdge)
}
// Ignore tag if it is a dummy UnnamedInputTag
if tag == graph.UnnamedInputTag {
tag = fmt.Sprintf("i%v", edge.External.InputsMap[tag])
}
inputs[tag] = nodeID(n)
}
spec := &pipepb.FunctionSpec{
Urn: edge.External.Urn,
Payload: edge.External.Payload,
}
transform := &pipepb.PTransform{
UniqueName: namedEdge.Name,
Spec: spec,
Inputs: inputs,
EnvironmentId: m.addDefaultEnv(),View on GitHub (pinned to 12126d8942)
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
Example fix
// before
if _, err := m.addNode(n); err != nil {
return "", errors.Wrapf(err, "failed to expand cross language transform for edge: %v", namedEdge)
}
// after — log the offending node/tag for diagnosis
if _, err := m.addNode(n); err != nil {
return "", errors.Wrapf(err, "failed to expand cross language transform for edge %v input tag %q", namedEdge, tag)
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify inputs are plain, marshalable PCollections before CrossLanguage
for _, in := range extInputs {
if in == nil || in.Coder == nil {
return errors.New("external transform input missing coder")
}
} Type guard
func validExternalInput(n *graph.Node) bool { return n != nil && n.Coder != nil && n.WindowingStrategy() != nil } Try / catch
if err := beam.Run(ctx, pr); err != nil {
var wrapped *errors.Wrapped
if errors.As(err, &wrapped) && strings.Contains(err.Error(), "failed to expand cross language transform") {
log.Printf("cross-language expansion failed: %v", err)
// fall back to pure-Go transform or fix expansion service
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- mismatch'd counts between External tags (%v) and inputs (%v)
- mismatch'd counts between External tags (%v) and outputs (%v
- res.GetError()
- invalid scope
- unknown atomic type: %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/1b0a59fa7d647754.
Report an issue: GitHub.