apache/beam · error

provided transform_name_mapping for a batch pipeline, did…

Error message

provided transform_name_mapping for a batch pipeline, did you mean to construct a streaming pipeline?

What it means

transform_name_mapping is only meaningful for streaming Dataflow job updates (mapping transform names so an update replaces the right stages). getJobOptions rejects the flag when the pipeline was constructed as batch (streaming=false), because batch jobs cannot use name-mapped updates.

Solutions

  1. Remove --transform_name_mapping for batch pipelines
  2. If an update is intended, construct the pipeline as streaming (withbeam.Streaming / --streaming) so the flag is allowed
  3. Also ensure --update is set, since a second check requires it when the mapping is present

Example fix

// before
--streaming=false --update --transform_name_mapping='{"old":"new"}'
// after
--streaming --update --transform_name_mapping='{"old":"new"}'
Defensive patterns

Strategy: validation

Validate before calling

if transformMapping != "" && !streaming {
    return errors.New("transform_name_mapping requires a streaming pipeline")
}

Prevention

When it happens

Trigger: Submitting a batch pipeline (no streaming option / source is bounded) while --transform_name_mapping=<json> is set.

Common situations: Reusing a streaming launch script's flag set for a batch job; leaving the flag in CI config after switching the pipeline to batch.

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/d936e801cd428c44. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/runners/dataflow/dataflow.go:310

		perf.EnableProfCaptureHook("gcs_profile_writer", *cpuProfiling)
	}

	if *autoscalingAlgorithm != "" {
		if *autoscalingAlgorithm != "NONE" && *autoscalingAlgorithm != "THROUGHPUT_BASED" {
			return nil, errors.New("invalid autoscaling algorithm. Use --autoscaling_algorithm=(NONE|THROUGHPUT_BASED)")
		}
	}

	if *flexRSGoal != "" {
		switch *flexRSGoal {
		case "FLEXRS_UNSPECIFIED", "FLEXRS_SPEED_OPTIMIZED", "FLEXRS_COST_OPTIMIZED":
			// valid values
		default:
			return nil, errors.Errorf("invalid flex resource scheduling goal. Got %q; Use --flexrs_goal=(FLEXRS_UNSPECIFIED|FLEXRS_SPEED_OPTIMIZED|FLEXRS_COST_OPTIMIZED)", *flexRSGoal)
		}
	}
	if !streaming && *transformMapping != "" {
		return nil, errors.New("provided transform_name_mapping for a batch pipeline, did you mean to construct a streaming pipeline?")
	}
	if !*update && *transformMapping != "" {
		return nil, errors.New("provided transform_name_mapping without setting the --update flag, so the pipeline would not be updated")
	}
	var updateTransformMapping map[string]string
	if *transformMapping != "" {
		if err := json.Unmarshal([]byte(*transformMapping), &updateTransformMapping); err != nil {
			return nil, errors.Wrapf(err, "error reading --transform_name_mapping flag as JSON")
		}
	}
	if *usePublicIPs == *noUsePublicIPs {
		useSet := isFlagPassed("use_public_ips")
		noUseSet := isFlagPassed("no_use_public_ips")
		// If use_public_ips was explicitly set but no_use_public_ips was not, use that value
		// We take the explicit value of no_use_public_ips if it was set but use_public_ips was not.
		if useSet && !noUseSet {
			*noUsePublicIPs = !*usePublicIPs
		} else if useSet && noUseSet {

View on GitHub (pinned to 12126d8942)