apache/beam · error
mismatched number of named outputs: received - %v expected -
Error message
mismatched number of named outputs: received - %v expected - %v
What it means
VerifyNamedOutputs checks that a cross-language transform's expanded outputs match the external transform's expected outputs map. This panic fires when the number of outputs produced by the expanded (remote) transform differs from the number in ext.OutputsMap.
Source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/xlang.go:135
outputs := t.GetOutputs()
for tag, nodeID := range outputs {
if pcolID, exists := idxMap[nodeID]; exists {
outputs[tag] = pcolID
}
}
}
}
// VerifyNamedOutputs ensures the expanded outputs correspond to the correct and expected named outputs
func VerifyNamedOutputs(ext *graph.ExternalTransform) {
transform, err := ExpandedTransform(ext.Expanded)
if err != nil {
panic(err)
}
expandedOutputs := transform.GetOutputs()
if len(expandedOutputs) != len(ext.OutputsMap) {
panic(errors.Errorf("mismatched number of named outputs:\nreceived - %v\nexpected - %v", len(expandedOutputs), len(ext.OutputsMap)))
}
for tag := range ext.OutputsMap {
_, exists := expandedOutputs[tag]
if tag != graph.UnnamedOutputTag && !exists {
panic(errors.Errorf("missing named output in expanded transform: %v is expected in %v", tag, expandedOutputs))
}
if tag == graph.UnnamedOutputTag && len(expandedOutputs) > 1 {
panic(errors.Errorf("mismatched number of unnamed outputs:\nreceived - %v\nexpected - 1", len(expandedOutputs)))
}
}
}
// ResolveOutputIsBounded updates each Output node with respect to the received
// expanded components to reflect if it is bounded or not
func ResolveOutputIsBounded(e *graph.MultiEdge, isBoundedUpdater func(*graph.Node, bool)) {
ext := e.External
exp := ext.ExpandedView on GitHub (pinned to 12126d8942)
Solutions
- Align the number of beam.CrossTransform outputs with the transform's actual outputs in the expansion service.
- Restart/update the expansion service so its transform version matches the client SDK.
- Check expansion logs to confirm the expanded transform's output tags and adjust the OutputsMap.
Example fix
// before
x := xlang.CrossTransform(scope, ext, xlang.UnderlyingMethod("v1"), xlang.Output("out", "a"))
// after
x := xlang.CrossTransform(scope, ext, xlang.UnderlyingMethod("v1"), xlang.Output("out", "a"), xlang.Output("out2", "b")) Defensive patterns
Strategy: validation
Validate before calling
if got, want := len(expandedOutputs), len(outputsMap); got != want {
return fmt.Errorf("expansion returned %d outputs, declared %d", got, want)
} Try / catch
defer func() {
if r := recover(); r != nil {
log.Fatalf("cross-language expansion mismatch: %v", r)
}
}() Prevention
- Declare exactly as many outputs as the remote transform emits.
- Keep the expansion service and SDK versions in sync.
- Inspect expansion service output tags when wiring CrossTransform outputs.
When it happens
Trigger: Calling TryCrossLanguage/Expand for an external transform whose expansion response from the expansion service returns a different count of output PCollections than the tags declared by beam.CrossTransform/Output calls.
Common situations: Expansion service serving a different version of the transform than the local SDK expects; declaring fewer/more named outputs than the transform actually emits; stale expansion service jar/container.
Related errors
- res.GetError()
- tried cross-language for %v against %v and failed
- Could not find coder for URN " + urn
- type annotation for multiple outputs is not allowed yet: %s
- invalid scope
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/b7dd3d5fc526d20c.
Report an issue: GitHub.