apache/beam · critical

inputs already set as: %v

Error message

inputs already set as: 
%v

What it means

ExternalTransform.WithNamedInputs sets the tag→input-index map used for cross-language transforms. It is a builder method that must be called at most once; calling it again on an ExternalTransform whose InputsMap is already non-nil panics with 'inputs already set as: ...'.

Source

Thrown at sdks/go/pkg/beam/core/graph/xlang.go:80

// Expanded field.
type ExternalTransform struct {
	Namespace string

	Urn           string
	Payload       []byte
	ExpansionAddr string

	InputsMap  map[string]int
	OutputsMap map[string]int

	Expanded *ExpandedTransform
}

// WithNamedInputs adds a map (tag -> index of Inbound in MultiEdge.Input)
// of named inputs corresponsing to ExternalTransform's InputsMap
func (ext ExternalTransform) WithNamedInputs(inputsMap map[string]int) ExternalTransform {
	if ext.InputsMap != nil {
		panic(errors.Errorf("inputs already set as: \n%v", ext.InputsMap))
	}
	ext.InputsMap = inputsMap
	return ext
}

// WithNamedOutputs adds a map (tag -> index of Outbound in MultiEdge.Output)
// of named outputs corresponsing to ExternalTransform's OutputsMap
func (ext ExternalTransform) WithNamedOutputs(outputsMap map[string]int) ExternalTransform {
	if ext.OutputsMap != nil {
		panic(errors.Errorf("outputTypes already set as: \n%v", ext.OutputsMap))
	}
	ext.OutputsMap = outputsMap
	return ext
}

// NewNamespaceGenerator returns a functions that generates a random string of n alphabets
func NewNamespaceGenerator(n int) func() string {
	const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

View on GitHub (pinned to 12126d8942)

Solutions

  1. Call WithNamedInputs exactly once per ExternalTransform; drop the duplicate call.
  2. If inputs may vary, create a fresh ExternalTransform (e.g. via beam.CrossLanguage/payload constructor) before calling WithNamedInputs.
  3. Guard builder code: only invoke when InputsMap is nil.
  4. The panic message prints the existing map — compare it with the intended inputsMap to spot the conflicting call site.

Example fix

// before
ext = ext.WithNamedInputs(m)
ext = ext.WithNamedInputs(m) // panics
// after
if ext.InputsMap == nil {
    ext = ext.WithNamedInputs(m)
}
Defensive patterns

Strategy: validation

Validate before calling

if ext.InputsMap == nil {
    ext = ext.WithNamedInputs(inputsMap)
}

Try / catch

func safeWithInputs(ext graph.ExternalTransform, m map[string]int) (r graph.ExternalTransform) {
    defer func() { if rec := recover(); rec != nil { log.Printf("inputs already set: %v", rec) } }()
    return ext.WithNamedInputs(m)
}

Prevention

When it happens

Trigger: Calling WithNamedInputs twice on the same ExternalTransform value (e.g. in a loop or builder chain repeated by mistake), before expanding the external transform.

Common situations: Builder-style code that applies WithNamedInputs in both a helper and the caller; retry/re-application logic re-running the builder; accidental method chaining duplication.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/9bee4aefa07a83df. Report an issue: GitHub.