{"record":{"id":"ffcc98d7a14b3bcc","repo":"apache/beam","slug":"outputtypes-already-set-as-v","errorCode":null,"errorMessage":"outputTypes already set as: \n%v","messagePattern":"outputTypes already set as: \n(.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"sdks/go/pkg/beam/core/graph/xlang.go","lineNumber":90,"sourceCode":"\n\tExpanded *ExpandedTransform\n}\n\n// WithNamedInputs adds a map (tag -> index of Inbound in MultiEdge.Input)\n// of named inputs corresponsing to ExternalTransform's InputsMap\nfunc (ext ExternalTransform) WithNamedInputs(inputsMap map[string]int) ExternalTransform {\n\tif ext.InputsMap != nil {\n\t\tpanic(errors.Errorf(\"inputs already set as: \\n%v\", ext.InputsMap))\n\t}\n\text.InputsMap = inputsMap\n\treturn ext\n}\n\n// WithNamedOutputs adds a map (tag -> index of Outbound in MultiEdge.Output)\n// of named outputs corresponsing to ExternalTransform's OutputsMap\nfunc (ext ExternalTransform) WithNamedOutputs(outputsMap map[string]int) ExternalTransform {\n\tif ext.OutputsMap != nil {\n\t\tpanic(errors.Errorf(\"outputTypes already set as: \\n%v\", ext.OutputsMap))\n\t}\n\text.OutputsMap = outputsMap\n\treturn ext\n}\n\n// NewNamespaceGenerator returns a functions that generates a random string of n alphabets\nfunc NewNamespaceGenerator(n int) func() string {\n\tconst letters = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n\tconst (\n\t\tletterIDBits = 6                   // 6 bits to represent a letter index\n\t\tletterIDMask = 1<<letterIDBits - 1 // All 1-bits, as many as letterIDBits\n\t\tletterIDMax  = 63 / letterIDBits   // # of letter indices fitting in 63 bits\n\t)\n\n\tvar src = rand.NewSource(time.Now().UnixNano())\n\n\trandom := func() string {\n\t\tsb := strings.Builder{}","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/xlang.go#L72-L108","documentation":"ExternalTransform.WithNamedOutputs sets the tag→output-index map for cross-language transforms. Like WithNamedInputs it may only be called once; a second call when OutputsMap is already set panics with 'outputTypes already set as: ...'.","triggerScenarios":"Calling WithNamedOutputs twice on the same ExternalTransform (duplicate builder invocation), before the transform is expanded into the graph.","commonSituations":"Chaining builder calls in two places (helper + caller); re-running construction logic on a retained ExternalTransform; copy-paste duplication when wiring multi-output external transforms.","solutions":["Call WithNamedOutputs exactly once per ExternalTransform; remove the redundant call.","Construct a new ExternalTransform if a different output map must be applied.","Condition the call on `ext.OutputsMap == nil` in builder helpers.","Use the panic's printed existing map to identify and reconcile the conflicting call site."],"exampleFix":"// before\next = ext.WithNamedOutputs(outs)\next = ext.WithNamedOutputs(outs2) // panics\n// after\next = ext.WithNamedOutputs(outs)","handlingStrategy":"validation","validationCode":"if ext.OutputsMap == nil {\n    ext = ext.WithNamedOutputs(outputsMap)\n}","typeGuard":null,"tryCatchPattern":"func safeWithOutputs(ext graph.ExternalTransform, m map[string]int) (r graph.ExternalTransform) {\n    defer func() { if rec := recover(); rec != nil { log.Printf(\"outputs already set: %v\", rec) } }()\n    return ext.WithNamedOutputs(m)\n}","preventionTips":["Call WithNamedOutputs once per ExternalTransform, ideally at construction time.","Create a fresh ExternalTransform when a different output map is needed."],"tags":["beam","go","xlang","builder","panic"],"backgroundTag":"conflicting-config-options","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}