apache/beam · error
missing named output in expanded transform
Error message
missing named output in expanded transform: %v is expected in %v
What it means
During VerifyNamedOutputs each expected tag from ext.OutputsMap must exist in the expanded transform's outputs. This panic fires when a named (non-empty) tag is declared locally but absent from the expansion service's expanded outputs.
Solutions
- Correct output tag names to exactly match the remote transform's output tags.
- Verify the expansion URN and underlying method select the intended transform version.
- Query the expansion service for the transform's output tag list and regenerate the outputs map.
Example fix
// before
xlang.Output("outpu", "a") // typo
// after
xlang.Output("output", "a") Defensive patterns
Strategy: validation
Validate before calling
for tag := range outputsMap {
if tag != "" {
if _, ok := expandedOutputs[tag]; !ok {
return fmt.Errorf("tag %q not in expanded outputs %v", tag, expandedOutputs)
}
}
} Try / catch
defer func() {
if r := recover(); r != nil {
log.Fatalf("missing named output during expansion: %v", r)
}
}() Prevention
- Copy output tag names from the transform's documentation or expansion logs, never by memory.
- Verify the URN/method selects the intended transform variant.
- Test expansions against the target expansion service version in CI.
When it happens
Trigger: An output tag passed to beam.CrossTransform/Output is not present in the expandedOutputs map returned by the expansion service, while total counts happen to match.
Common situations: Typo or naming mismatch between local output tag and the remote transform's output tag; using the wrong URN/method so a different transform variant is expanded; version drift between SDK and expansion service.
Related errors
- mismatched number of unnamed outputs: received
- attempted to add namespace to missing coder id
- attempted to add namespace to missing windowing strategy id
- failed to add output coder to coder registry
- failed to expand cross language transform for edge
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/772070d2079d4f17.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/xlang.go:141
}
}
// 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.Expanded
components, err := ExpandedComponents(exp)
if err != nil {
panic(err)
}
expandedPCollections := components.GetPcollections()
transform, err := ExpandedTransform(exp)View on GitHub (pinned to 12126d8942)