apache/beam · error

bad parameter type for %s: %v

Error message

bad parameter type for %s: %v

What it means

funcx.New validates each parameter of a user function against known kinds (context, event time, emitters, iterators, multi-maps, etc.). When the parameter is a func type that looks like an emitter but is structurally illegal (unfoldEmit fails — e.g. emits interface{} or has a non-concrete parameter), IsMalformedEmit returns true and the wrapped error is raised as "bad parameter type for <fnName>: <type>".

Source

Thrown at sdks/go/pkg/beam/core/funcx/fn.go:434

			kind = FnRTracker
		case t.Implements(reflect.TypeOf((*sdf.WatermarkEstimator)(nil)).Elem()):
			kind = FnWatermarkEstimator
		case typex.IsContainer(t), typex.IsConcrete(t), typex.IsUniversal(t):
			kind = FnValue
		case IsEmit(t):
			kind = FnEmit
		case IsIter(t):
			kind = FnIter
		case IsReIter(t):
			kind = FnReIter
		case IsMultiMap(t):
			kind = FnMultiMap
		case t == typex.PaneInfoType:
			kind = FnPane
		default:
			// Error cases
			if ok, err := IsMalformedEmit(t); ok {
				return nil, errors.Wrapf(err, "bad parameter type for %s: %v", fn.Name(), t)
			}
			if ok, err := IsMalformedIter(t); ok {
				return nil, errors.Wrapf(err, "bad parameter type for %s: %v", fn.Name(), t)
			}
			if ok, err := IsMalformedReIter(t); ok {
				return nil, errors.Wrapf(err, "bad parameter type for %s: %v", fn.Name(), t)
			}
			if ok, err := IsMalformedMultiMap(t); ok {
				return nil, errors.Wrapf(err, "bad parameter type for %s: %v", fn.Name(), t)
			}
			return nil, errors.Errorf("bad parameter type for %s: %v", fn.Name(), t)
		}

		param = append(param, FnParam{Kind: kind, T: t})
	}

	var ret []ReturnParam
	for i := 0; i < fn.Type().NumOut(); i++ {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Read the wrapped cause: it names the illegal parameter (e.g. "Type interface{} isn't a supported PCollection type" or errIllegalParametersInEmit).
  2. Make emitted element types concrete and JSON-codable (exported struct, basic type, or typex-registered type).
  3. Reduce emitter arity to at most 2 params: optional typex.EventTime first, then 1–2 concrete element types.
  4. Remove return values from emit funcs — emitters must have no outputs (NumOut == 0).
  5. Replace interface{} / any parameters with a concrete type or a typex universal/container type.

Example fix

// before
func (f *MyFn) ProcessElement(e string, emit func(int, string, bool)) { ... } // 3 params: malformed emit

// after
func (f *MyFn) ProcessElement(e string, emit func(MyResult)) { ... } // 1 concrete element type
Defensive patterns

Strategy: validation

Validate before calling

if ok, err := funcx.IsMalformedEmit(reflect.TypeOf(emitFn)); ok {
  return fmt.Errorf("emit signature rejected: %w", err)
}

Type guard

func isValidEmit(t reflect.Type) bool {
  ok, err := funcx.IsMalformedEmit(t)
  return ok == false && err == nil && funcx.IsEmit(t)
}

Try / catch

fn, err := funcx.New(reflect.ValueOf(processFn))
if err != nil {
  return fmt.Errorf("DoFn %T rejected: %w", processFn, err)
}

Prevention

When it happens

Trigger: Binding a DoFn/CombineFn/DoFn process method whose parameter is a func(...) with return values, or an emitter whose element type is interface{} / a non-concrete type, or an emitter taking more than 2 parameters (beyond the optional EventTime).

Common situations: Writing emit funcs with wrong arity (func(T, U, V) instead of max T plus EventTime), emitting interface{} or unexported types, copying a signature that returns a value, typo in typex.EventTime placement.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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